From d41c53f191b8b86f43787fb52b3b4de104116161 Mon Sep 17 00:00:00 2001 From: Antoine Beyeler <49431240+abey79@users.noreply.github.com> Date: Tue, 17 Dec 2024 12:14:58 +0100 Subject: [PATCH 01/30] Add better support for scrolling content to our modals (#8492) ### What This PR builds proper scrollability to our modals, thereby fixing: - an ugly glitch with large add/remove entity modal - add view/container modal not scrollable with very small viewer window size #### Before image #### After image image --------- Co-authored-by: Clement Rey --- .../src/view_entity_picker.rs | 18 +-- crates/viewer/re_ui/src/modal.rs | 144 +++++++++++++++--- .../src/ui/add_view_or_container_modal.rs | 4 +- .../check_modal_scrolling.py | 46 ++++++ 4 files changed, 171 insertions(+), 41 deletions(-) create mode 100644 tests/python/release_checklist/check_modal_scrolling.py diff --git a/crates/viewer/re_selection_panel/src/view_entity_picker.rs b/crates/viewer/re_selection_panel/src/view_entity_picker.rs index 513111b3bb9c..d1a6b7ecb4fc 100644 --- a/crates/viewer/re_selection_panel/src/view_entity_picker.rs +++ b/crates/viewer/re_selection_panel/src/view_entity_picker.rs @@ -1,4 +1,3 @@ -use egui::NumExt as _; use itertools::Itertools; use nohash_hasher::IntMap; @@ -39,6 +38,7 @@ impl ViewEntityPicker { re_ui::modal::ModalWrapper::new("Add/remove Entities") .default_height(640.0) .full_span_content(true) + .scrollable([false, true]) }, |ui, open| { let Some(view_id) = &self.view_id else { @@ -51,21 +51,7 @@ impl ViewEntityPicker { return; }; - // Make the modal size less jumpy and work around https://github.com/emilk/egui/issues/5138 - // TODO(ab): move that boilerplate to `ModalWrapper` by adding a `scrollable` flag. - let max_height = 0.85 * ui.ctx().screen_rect().height(); - let min_height = 0.3 * ui.ctx().screen_rect().height().at_most(max_height); - - egui::ScrollArea::vertical() - .min_scrolled_height(max_height) - .max_height(max_height) - .show(ui, |ui| { - add_entities_ui(ctx, ui, view); - - if ui.min_rect().height() < min_height { - ui.add_space(min_height - ui.min_rect().height()); - } - }); + add_entities_ui(ctx, ui, view); }, ); } diff --git a/crates/viewer/re_ui/src/modal.rs b/crates/viewer/re_ui/src/modal.rs index e6f7b9113c18..1f5963ee7d65 100644 --- a/crates/viewer/re_ui/src/modal.rs +++ b/crates/viewer/re_ui/src/modal.rs @@ -1,3 +1,5 @@ +use eframe::emath::NumExt; + use crate::{DesignTokens, UiExt as _}; /// Helper object to handle a [`ModalWrapper`] window. @@ -83,6 +85,7 @@ pub struct ModalWrapper { min_height: Option, default_height: Option, full_span_content: bool, + scrollable: egui::Vec2b, } impl ModalWrapper { @@ -94,6 +97,7 @@ impl ModalWrapper { min_height: None, default_height: None, full_span_content: false, + scrollable: false.into(), } } @@ -131,6 +135,13 @@ impl ModalWrapper { self } + /// Enclose the contents in a scroll area. + #[inline] + pub fn scrollable(mut self, scrollable: impl Into) -> Self { + self.scrollable = scrollable.into(); + self + } + /// Show the modal window. /// /// Typically called by [`ModalHandler::ui`]. @@ -148,7 +159,7 @@ impl ModalWrapper { area = area.default_height(default_height); } - let modal_response = egui::Modal::new("add_view_or_container_modal".into()) + let modal_response = egui::Modal::new(id.with("modal")) .frame(egui::Frame { fill: ctx.style().visuals.panel_fill, ..Default::default() @@ -168,38 +179,82 @@ impl ModalWrapper { ui.set_min_height(min_height); } - egui::Frame { - inner_margin: egui::Margin::symmetric(DesignTokens::view_padding(), 0.0), - ..Default::default() - } + // + // Title bar + // + + view_padding_frame(&ViewPaddingFrameParams { + left_and_right: true, + top: true, + bottom: false, + }) .show(ui, |ui| { - ui.add_space(DesignTokens::view_padding()); Self::title_bar(ui, &self.title, &mut open); ui.add_space(DesignTokens::view_padding()); ui.full_span_separator(); + }); - if self.full_span_content { - // no further spacing for the content UI - content_ui(ui, &mut open) - } else { - // we must restore vertical spacing and add view padding at the bottom - ui.add_space(item_spacing_y); - - egui::Frame { - inner_margin: egui::Margin { - bottom: DesignTokens::view_padding(), - ..Default::default() - }, - ..Default::default() + // + // Inner content + // + + let wrapped_content_ui = |ui: &mut egui::Ui, open: &mut bool| -> R { + // We always have side margin, but these must happen _inside_ the scroll area + // (if any). Otherwise, the scroll bar is not snug with the right border and + // may interfere with the action buttons of `ListItem`s. + view_padding_frame(&ViewPaddingFrameParams { + left_and_right: true, + top: false, + bottom: false, + }) + .show(ui, |ui| { + if self.full_span_content { + // no further spacing for the content UI + content_ui(ui, open) + } else { + // we must restore vertical spacing and add view padding at the bottom + ui.add_space(item_spacing_y); + + view_padding_frame(&ViewPaddingFrameParams { + left_and_right: false, + top: false, + bottom: true, + }) + .show(ui, |ui| { + ui.spacing_mut().item_spacing.y = item_spacing_y; + content_ui(ui, open) + }) + .inner } + }) + .inner + }; + + // + // Optional scroll area + // + + if self.scrollable.any() { + // Make the modal size less jumpy and work around https://github.com/emilk/egui/issues/5138 + let max_height = 0.85 * ui.ctx().screen_rect().height(); + let min_height = 0.3 * ui.ctx().screen_rect().height().at_most(max_height); + + egui::ScrollArea::new(self.scrollable) + .min_scrolled_height(max_height) + .max_height(max_height) .show(ui, |ui| { - ui.spacing_mut().item_spacing.y = item_spacing_y; - content_ui(ui, &mut open) + let res = wrapped_content_ui(ui, &mut open); + + if ui.min_rect().height() < min_height { + ui.add_space(min_height - ui.min_rect().height()); + } + + res }) .inner - } - }) - .inner + } else { + wrapped_content_ui(ui, &mut open) + } }); if modal_response.should_close() { @@ -230,3 +285,44 @@ impl ModalWrapper { }); } } + +struct ViewPaddingFrameParams { + left_and_right: bool, + top: bool, + bottom: bool, +} + +/// Utility to produce a [`egui::Frame`] with padding on some sides. +#[inline] +fn view_padding_frame(params: &ViewPaddingFrameParams) -> egui::Frame { + let ViewPaddingFrameParams { + left_and_right, + top, + bottom, + } = *params; + egui::Frame { + inner_margin: egui::Margin { + left: if left_and_right { + DesignTokens::view_padding() + } else { + 0.0 + }, + right: if left_and_right { + DesignTokens::view_padding() + } else { + 0.0 + }, + top: if top { + DesignTokens::view_padding() + } else { + 0.0 + }, + bottom: if bottom { + DesignTokens::view_padding() + } else { + 0.0 + }, + }, + ..Default::default() + } +} diff --git a/crates/viewer/re_viewport_blueprint/src/ui/add_view_or_container_modal.rs b/crates/viewer/re_viewport_blueprint/src/ui/add_view_or_container_modal.rs index 4a38ee15a48f..63f2fc83e02f 100644 --- a/crates/viewer/re_viewport_blueprint/src/ui/add_view_or_container_modal.rs +++ b/crates/viewer/re_viewport_blueprint/src/ui/add_view_or_container_modal.rs @@ -1,11 +1,12 @@ //! Modal for adding a new view of container to an existing target container. -use crate::{ViewBlueprint, ViewportBlueprint}; use re_ui::UiExt as _; use re_viewer_context::{ blueprint_id_to_tile_id, icon_for_container_kind, ContainerId, RecommendedView, ViewerContext, }; +use crate::{ViewBlueprint, ViewportBlueprint}; + #[derive(Default)] pub struct AddViewOrContainerModal { target_container: Option, @@ -30,6 +31,7 @@ impl AddViewOrContainerModal { re_ui::modal::ModalWrapper::new("Add view or container") .min_width(500.0) .full_span_content(true) + .scrollable([false, true]) }, |ui, keep_open| modal_ui(ui, ctx, viewport, self.target_container, keep_open), ); diff --git a/tests/python/release_checklist/check_modal_scrolling.py b/tests/python/release_checklist/check_modal_scrolling.py new file mode 100644 index 000000000000..8859f69acc17 --- /dev/null +++ b/tests/python/release_checklist/check_modal_scrolling.py @@ -0,0 +1,46 @@ +from __future__ import annotations + +import os +from argparse import Namespace +from uuid import uuid4 + +import rerun as rr +import rerun.blueprint as rrb + +README = """\ +# Modal scrolling + +* Select the 2D view +* Open the Entity Path Filter modal +* Make sure it behaves properly, including scrolling +""" + + +def log_readme() -> None: + rr.log("readme", rr.TextDocument(README, media_type=rr.MediaType.MARKDOWN), timeless=True) + + +def log_many_entities() -> None: + for i in range(0, 1000): + rr.log(f"points/{i}", rr.Points2D([(i, i)])) + + +def run(args: Namespace) -> None: + rr.script_setup( + args, + f"{os.path.basename(__file__)}", + recording_id=uuid4(), + default_blueprint=rrb.Grid(rrb.Spatial2DView(origin="/"), rrb.TextDocumentView(origin="readme")), + ) + + log_readme() + log_many_entities() + + +if __name__ == "__main__": + import argparse + + parser = argparse.ArgumentParser(description="Interactive release checklist") + rr.script_add_args(parser) + args = parser.parse_args() + run(args) From 6b00c77ceb36d549fedba1efc9319b20e65b74f5 Mon Sep 17 00:00:00 2001 From: Antoine Beyeler <49431240+abey79@users.noreply.github.com> Date: Tue, 17 Dec 2024 12:27:28 +0100 Subject: [PATCH 02/30] Improve the tooltip of the `Force*` graph view properties (#8501) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### Related - fixes #8456 ### What ☝🏻 image --- .../blueprint/archetypes/force_center.fbs | 4 ++- .../archetypes/force_collision_radius.fbs | 6 +++-- .../rerun/blueprint/archetypes/force_link.fbs | 4 ++- .../blueprint/archetypes/force_many_body.fbs | 5 +++- .../blueprint/archetypes/force_position.fbs | 4 ++- .../src/blueprint/archetypes/force_center.rs | 8 ++++-- .../archetypes/force_collision_radius.rs | 10 +++++--- .../src/blueprint/archetypes/force_link.rs | 8 ++++-- .../blueprint/archetypes/force_many_body.rs | 10 ++++++-- .../blueprint/archetypes/force_position.rs | 8 ++++-- crates/store/re_types/src/reflection/mod.rs | 25 +++++++++++-------- .../reference/types/views/graph_view.md | 10 ++++---- .../blueprint/archetypes/force_center.hpp | 8 ++++-- .../archetypes/force_collision_radius.hpp | 10 +++++--- .../rerun/blueprint/archetypes/force_link.hpp | 8 ++++-- .../blueprint/archetypes/force_many_body.hpp | 10 ++++++-- .../blueprint/archetypes/force_position.hpp | 8 ++++-- .../blueprint/archetypes/force_center.py | 8 ++++-- .../archetypes/force_collision_radius.py | 10 +++++--- .../rerun/blueprint/archetypes/force_link.py | 8 ++++-- .../blueprint/archetypes/force_many_body.py | 10 ++++++-- .../blueprint/archetypes/force_position.py | 8 ++++-- 22 files changed, 136 insertions(+), 54 deletions(-) diff --git a/crates/store/re_types/definitions/rerun/blueprint/archetypes/force_center.fbs b/crates/store/re_types/definitions/rerun/blueprint/archetypes/force_center.fbs index c3b477bf49d0..a574b9c696c0 100644 --- a/crates/store/re_types/definitions/rerun/blueprint/archetypes/force_center.fbs +++ b/crates/store/re_types/definitions/rerun/blueprint/archetypes/force_center.fbs @@ -4,7 +4,9 @@ namespace rerun.blueprint.archetypes; struct ForceCenter ( "attr.rerun.scope": "blueprint" ) { - /// Whether the force is enabled. + /// Whether the center force is enabled. + /// + /// The center force tries to move the center of mass of the graph towards the origin. enabled: rerun.blueprint.components.Enabled ("attr.rerun.component_optional", nullable, order: 100); /// The strength of the force. diff --git a/crates/store/re_types/definitions/rerun/blueprint/archetypes/force_collision_radius.fbs b/crates/store/re_types/definitions/rerun/blueprint/archetypes/force_collision_radius.fbs index 9ffcf43376ff..f4a4e760b59a 100644 --- a/crates/store/re_types/definitions/rerun/blueprint/archetypes/force_collision_radius.fbs +++ b/crates/store/re_types/definitions/rerun/blueprint/archetypes/force_collision_radius.fbs @@ -1,10 +1,12 @@ namespace rerun.blueprint.archetypes; -/// Resolves collisions between the bounding spheres, according to the radius of the nodes. +/// Resolves collisions between the bounding circles, according to the radius of the nodes. struct ForceCollisionRadius ( "attr.rerun.scope": "blueprint" ) { - /// Whether the force is enabled. + /// Whether the collision force is enabled. + /// + /// The collision force resolves collisions between nodes based on the bounding circle defined by their radius. enabled: rerun.blueprint.components.Enabled ("attr.rerun.component_optional", nullable, order: 100); /// The strength of the force. diff --git a/crates/store/re_types/definitions/rerun/blueprint/archetypes/force_link.fbs b/crates/store/re_types/definitions/rerun/blueprint/archetypes/force_link.fbs index fc963b757cf3..2d34b1c936ae 100644 --- a/crates/store/re_types/definitions/rerun/blueprint/archetypes/force_link.fbs +++ b/crates/store/re_types/definitions/rerun/blueprint/archetypes/force_link.fbs @@ -4,7 +4,9 @@ namespace rerun.blueprint.archetypes; struct ForceLink ( "attr.rerun.scope": "blueprint" ) { - /// Whether the force is enabled. + /// Whether the link force is enabled. + /// + /// The link force aims to achieve a target distance between two nodes that are connected by one ore more edges. enabled: rerun.blueprint.components.Enabled ("attr.rerun.component_optional", nullable, order: 100); /// The target distance between two nodes. diff --git a/crates/store/re_types/definitions/rerun/blueprint/archetypes/force_many_body.fbs b/crates/store/re_types/definitions/rerun/blueprint/archetypes/force_many_body.fbs index edafce01c777..abc576912fca 100644 --- a/crates/store/re_types/definitions/rerun/blueprint/archetypes/force_many_body.fbs +++ b/crates/store/re_types/definitions/rerun/blueprint/archetypes/force_many_body.fbs @@ -6,7 +6,10 @@ namespace rerun.blueprint.archetypes; struct ForceManyBody ( "attr.rerun.scope": "blueprint" ) { - /// Whether the force is enabled. + /// Whether the many body force is enabled. + /// + /// The many body force is applied on each pair of nodes in a way that ressembles an electrical charge. If the + /// strength is smaller than 0, it pushes nodes apart; if it is larger than 0, it pulls them together. enabled: rerun.blueprint.components.Enabled ("attr.rerun.component_optional", nullable, order: 100); /// The strength of the force. diff --git a/crates/store/re_types/definitions/rerun/blueprint/archetypes/force_position.fbs b/crates/store/re_types/definitions/rerun/blueprint/archetypes/force_position.fbs index 7ff9fd24d340..6689b95b48d7 100644 --- a/crates/store/re_types/definitions/rerun/blueprint/archetypes/force_position.fbs +++ b/crates/store/re_types/definitions/rerun/blueprint/archetypes/force_position.fbs @@ -4,7 +4,9 @@ namespace rerun.blueprint.archetypes; struct ForcePosition ( "attr.rerun.scope": "blueprint" ) { - /// Whether the force is enabled. + /// Whether the position force is enabled. + /// + /// The position force pulls nodes towards a specific position, similar to gravity. enabled: rerun.blueprint.components.Enabled ("attr.rerun.component_optional", nullable, order: 100); /// The strength of the force. diff --git a/crates/store/re_types/src/blueprint/archetypes/force_center.rs b/crates/store/re_types/src/blueprint/archetypes/force_center.rs index 9cb1870a5af5..5f12962b42dc 100644 --- a/crates/store/re_types/src/blueprint/archetypes/force_center.rs +++ b/crates/store/re_types/src/blueprint/archetypes/force_center.rs @@ -21,7 +21,9 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; /// **Archetype**: Tries to move the center of mass of the graph to the origin. #[derive(Clone, Debug)] pub struct ForceCenter { - /// Whether the force is enabled. + /// Whether the center force is enabled. + /// + /// The center force tries to move the center of mass of the graph towards the origin. pub enabled: Option, /// The strength of the force. @@ -207,7 +209,9 @@ impl ForceCenter { } } - /// Whether the force is enabled. + /// Whether the center force is enabled. + /// + /// The center force tries to move the center of mass of the graph towards the origin. #[inline] pub fn with_enabled( mut self, diff --git a/crates/store/re_types/src/blueprint/archetypes/force_collision_radius.rs b/crates/store/re_types/src/blueprint/archetypes/force_collision_radius.rs index 71055ab49f0f..9f4536a2b750 100644 --- a/crates/store/re_types/src/blueprint/archetypes/force_collision_radius.rs +++ b/crates/store/re_types/src/blueprint/archetypes/force_collision_radius.rs @@ -18,10 +18,12 @@ use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; -/// **Archetype**: Resolves collisions between the bounding spheres, according to the radius of the nodes. +/// **Archetype**: Resolves collisions between the bounding circles, according to the radius of the nodes. #[derive(Clone, Debug)] pub struct ForceCollisionRadius { - /// Whether the force is enabled. + /// Whether the collision force is enabled. + /// + /// The collision force resolves collisions between nodes based on the bounding circle defined by their radius. pub enabled: Option, /// The strength of the force. @@ -250,7 +252,9 @@ impl ForceCollisionRadius { } } - /// Whether the force is enabled. + /// Whether the collision force is enabled. + /// + /// The collision force resolves collisions between nodes based on the bounding circle defined by their radius. #[inline] pub fn with_enabled( mut self, diff --git a/crates/store/re_types/src/blueprint/archetypes/force_link.rs b/crates/store/re_types/src/blueprint/archetypes/force_link.rs index 9c6fe8aa11d2..f294b0eb9818 100644 --- a/crates/store/re_types/src/blueprint/archetypes/force_link.rs +++ b/crates/store/re_types/src/blueprint/archetypes/force_link.rs @@ -21,7 +21,9 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; /// **Archetype**: Aims to achieve a target distance between two nodes that are connected by an edge. #[derive(Clone, Debug)] pub struct ForceLink { - /// Whether the force is enabled. + /// Whether the link force is enabled. + /// + /// The link force aims to achieve a target distance between two nodes that are connected by one ore more edges. pub enabled: Option, /// The target distance between two nodes. @@ -249,7 +251,9 @@ impl ForceLink { } } - /// Whether the force is enabled. + /// Whether the link force is enabled. + /// + /// The link force aims to achieve a target distance between two nodes that are connected by one ore more edges. #[inline] pub fn with_enabled( mut self, diff --git a/crates/store/re_types/src/blueprint/archetypes/force_many_body.rs b/crates/store/re_types/src/blueprint/archetypes/force_many_body.rs index 9720ff5a4f17..026e249436d4 100644 --- a/crates/store/re_types/src/blueprint/archetypes/force_many_body.rs +++ b/crates/store/re_types/src/blueprint/archetypes/force_many_body.rs @@ -23,7 +23,10 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; /// If `strength` is smaller than 0, it pushes nodes apart, if it is larger than 0 it pulls them together. #[derive(Clone, Debug)] pub struct ForceManyBody { - /// Whether the force is enabled. + /// Whether the many body force is enabled. + /// + /// The many body force is applied on each pair of nodes in a way that ressembles an electrical charge. If the + /// strength is smaller than 0, it pushes nodes apart; if it is larger than 0, it pulls them together. pub enabled: Option, /// The strength of the force. @@ -211,7 +214,10 @@ impl ForceManyBody { } } - /// Whether the force is enabled. + /// Whether the many body force is enabled. + /// + /// The many body force is applied on each pair of nodes in a way that ressembles an electrical charge. If the + /// strength is smaller than 0, it pushes nodes apart; if it is larger than 0, it pulls them together. #[inline] pub fn with_enabled( mut self, diff --git a/crates/store/re_types/src/blueprint/archetypes/force_position.rs b/crates/store/re_types/src/blueprint/archetypes/force_position.rs index e106a452c2a2..cc74aa2aabf4 100644 --- a/crates/store/re_types/src/blueprint/archetypes/force_position.rs +++ b/crates/store/re_types/src/blueprint/archetypes/force_position.rs @@ -21,7 +21,9 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; /// **Archetype**: Similar to gravity, this force pulls nodes towards a specific position. #[derive(Clone, Debug)] pub struct ForcePosition { - /// Whether the force is enabled. + /// Whether the position force is enabled. + /// + /// The position force pulls nodes towards a specific position, similar to gravity. pub enabled: Option, /// The strength of the force. @@ -246,7 +248,9 @@ impl ForcePosition { } } - /// Whether the force is enabled. + /// Whether the position force is enabled. + /// + /// The position force pulls nodes towards a specific position, similar to gravity. #[inline] pub fn with_enabled( mut self, diff --git a/crates/store/re_types/src/reflection/mod.rs b/crates/store/re_types/src/reflection/mod.rs index 2deab0ebfb3c..05839fe7c80e 100644 --- a/crates/store/re_types/src/reflection/mod.rs +++ b/crates/store/re_types/src/reflection/mod.rs @@ -2040,8 +2040,9 @@ fn generate_archetype_reflection() -> ArchetypeReflectionMap { fields: vec![ ArchetypeFieldReflection { name : "enabled", display_name : "Enabled", component_name : "rerun.blueprint.components.Enabled" - .into(), docstring_md : "Whether the force is enabled.", is_required - : false, }, ArchetypeFieldReflection { name : "strength", + .into(), docstring_md : + "Whether the center force is enabled.\n\nThe center force tries to move the center of mass of the graph towards the origin.", + is_required : false, }, ArchetypeFieldReflection { name : "strength", display_name : "Strength", component_name : "rerun.blueprint.components.ForceStrength".into(), docstring_md : "The strength of the force.", is_required : false, }, @@ -2057,8 +2058,9 @@ fn generate_archetype_reflection() -> ArchetypeReflectionMap { fields: vec![ ArchetypeFieldReflection { name : "enabled", display_name : "Enabled", component_name : "rerun.blueprint.components.Enabled" - .into(), docstring_md : "Whether the force is enabled.", is_required - : false, }, ArchetypeFieldReflection { name : "strength", + .into(), docstring_md : + "Whether the collision force is enabled.\n\nThe collision force resolves collisions between nodes based on the bounding circle defined by their radius.", + is_required : false, }, ArchetypeFieldReflection { name : "strength", display_name : "Strength", component_name : "rerun.blueprint.components.ForceStrength".into(), docstring_md : "The strength of the force.", is_required : false, }, @@ -2079,8 +2081,9 @@ fn generate_archetype_reflection() -> ArchetypeReflectionMap { fields: vec![ ArchetypeFieldReflection { name : "enabled", display_name : "Enabled", component_name : "rerun.blueprint.components.Enabled" - .into(), docstring_md : "Whether the force is enabled.", is_required - : false, }, ArchetypeFieldReflection { name : "distance", + .into(), docstring_md : + "Whether the link force is enabled.\n\nThe link force aims to achieve a target distance between two nodes that are connected by one ore more edges.", + is_required : false, }, ArchetypeFieldReflection { name : "distance", display_name : "Distance", component_name : "rerun.blueprint.components.ForceDistance".into(), docstring_md : "The target distance between two nodes.", is_required : false, }, @@ -2101,8 +2104,9 @@ fn generate_archetype_reflection() -> ArchetypeReflectionMap { fields: vec![ ArchetypeFieldReflection { name : "enabled", display_name : "Enabled", component_name : "rerun.blueprint.components.Enabled" - .into(), docstring_md : "Whether the force is enabled.", is_required - : false, }, ArchetypeFieldReflection { name : "strength", + .into(), docstring_md : + "Whether the many body force is enabled.\n\nThe many body force is applied on each pair of nodes in a way that ressembles an electrical charge. If the\nstrength is smaller than 0, it pushes nodes apart; if it is larger than 0, it pulls them together.", + is_required : false, }, ArchetypeFieldReflection { name : "strength", display_name : "Strength", component_name : "rerun.blueprint.components.ForceStrength".into(), docstring_md : "The strength of the force.\n\nIf `strength` is smaller than 0, it pushes nodes apart, if it is larger than 0 it pulls them together.", @@ -2119,8 +2123,9 @@ fn generate_archetype_reflection() -> ArchetypeReflectionMap { fields: vec![ ArchetypeFieldReflection { name : "enabled", display_name : "Enabled", component_name : "rerun.blueprint.components.Enabled" - .into(), docstring_md : "Whether the force is enabled.", is_required - : false, }, ArchetypeFieldReflection { name : "strength", + .into(), docstring_md : + "Whether the position force is enabled.\n\nThe position force pulls nodes towards a specific position, similar to gravity.", + is_required : false, }, ArchetypeFieldReflection { name : "strength", display_name : "Strength", component_name : "rerun.blueprint.components.ForceStrength".into(), docstring_md : "The strength of the force.", is_required : false, }, diff --git a/docs/content/reference/types/views/graph_view.md b/docs/content/reference/types/views/graph_view.md index 7e39cfc769e4..e222d74616b7 100644 --- a/docs/content/reference/types/views/graph_view.md +++ b/docs/content/reference/types/views/graph_view.md @@ -14,30 +14,30 @@ Somethings outside of these bounds may also be visible due to letterboxing. ### `force_link` Allows to control the interaction between two nodes connected by an edge. -* `enabled`: Whether the force is enabled. +* `enabled`: Whether the link force is enabled. * `distance`: The target distance between two nodes. * `iterations`: Specifies how often this force should be applied per iteration. ### `force_many_body` A force between each pair of nodes that ressembles an electrical charge. -* `enabled`: Whether the force is enabled. +* `enabled`: Whether the many body force is enabled. * `strength`: The strength of the force. ### `force_position` Similar to gravity, this force pulls nodes towards a specific position. -* `enabled`: Whether the force is enabled. +* `enabled`: Whether the position force is enabled. * `strength`: The strength of the force. * `position`: The position where the nodes should be pulled towards. ### `force_collision_radius` Resolves collisions between the bounding spheres, according to the radius of the nodes. -* `enabled`: Whether the force is enabled. +* `enabled`: Whether the collision force is enabled. * `strength`: The strength of the force. * `iterations`: Specifies how often this force should be applied per iteration. ### `force_center` Tries to move the center of mass of the graph to the origin. -* `enabled`: Whether the force is enabled. +* `enabled`: Whether the center force is enabled. * `strength`: The strength of the force. ## API reference links diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/force_center.hpp b/rerun_cpp/src/rerun/blueprint/archetypes/force_center.hpp index 8c3854765b91..4a76fb9c2ff7 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/force_center.hpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/force_center.hpp @@ -19,7 +19,9 @@ namespace rerun::blueprint::archetypes { /// **Archetype**: Tries to move the center of mass of the graph to the origin. struct ForceCenter { - /// Whether the force is enabled. + /// Whether the center force is enabled. + /// + /// The center force tries to move the center of mass of the graph towards the origin. std::optional enabled; /// The strength of the force. @@ -36,7 +38,9 @@ namespace rerun::blueprint::archetypes { ForceCenter() = default; ForceCenter(ForceCenter&& other) = default; - /// Whether the force is enabled. + /// Whether the center force is enabled. + /// + /// The center force tries to move the center of mass of the graph towards the origin. ForceCenter with_enabled(rerun::blueprint::components::Enabled _enabled) && { enabled = std::move(_enabled); // See: https://github.com/rerun-io/rerun/issues/4027 diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/force_collision_radius.hpp b/rerun_cpp/src/rerun/blueprint/archetypes/force_collision_radius.hpp index 5b8ff3d1d511..f51201ee8bd0 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/force_collision_radius.hpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/force_collision_radius.hpp @@ -18,9 +18,11 @@ #include namespace rerun::blueprint::archetypes { - /// **Archetype**: Resolves collisions between the bounding spheres, according to the radius of the nodes. + /// **Archetype**: Resolves collisions between the bounding circles, according to the radius of the nodes. struct ForceCollisionRadius { - /// Whether the force is enabled. + /// Whether the collision force is enabled. + /// + /// The collision force resolves collisions between nodes based on the bounding circle defined by their radius. std::optional enabled; /// The strength of the force. @@ -42,7 +44,9 @@ namespace rerun::blueprint::archetypes { ForceCollisionRadius() = default; ForceCollisionRadius(ForceCollisionRadius&& other) = default; - /// Whether the force is enabled. + /// Whether the collision force is enabled. + /// + /// The collision force resolves collisions between nodes based on the bounding circle defined by their radius. ForceCollisionRadius with_enabled(rerun::blueprint::components::Enabled _enabled) && { enabled = std::move(_enabled); // See: https://github.com/rerun-io/rerun/issues/4027 diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/force_link.hpp b/rerun_cpp/src/rerun/blueprint/archetypes/force_link.hpp index 0d88538bc59b..b543152710b4 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/force_link.hpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/force_link.hpp @@ -20,7 +20,9 @@ namespace rerun::blueprint::archetypes { /// **Archetype**: Aims to achieve a target distance between two nodes that are connected by an edge. struct ForceLink { - /// Whether the force is enabled. + /// Whether the link force is enabled. + /// + /// The link force aims to achieve a target distance between two nodes that are connected by one ore more edges. std::optional enabled; /// The target distance between two nodes. @@ -42,7 +44,9 @@ namespace rerun::blueprint::archetypes { ForceLink() = default; ForceLink(ForceLink&& other) = default; - /// Whether the force is enabled. + /// Whether the link force is enabled. + /// + /// The link force aims to achieve a target distance between two nodes that are connected by one ore more edges. ForceLink with_enabled(rerun::blueprint::components::Enabled _enabled) && { enabled = std::move(_enabled); // See: https://github.com/rerun-io/rerun/issues/4027 diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/force_many_body.hpp b/rerun_cpp/src/rerun/blueprint/archetypes/force_many_body.hpp index c5267b3cf692..9b0e2686745d 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/force_many_body.hpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/force_many_body.hpp @@ -21,7 +21,10 @@ namespace rerun::blueprint::archetypes { /// /// If `strength` is smaller than 0, it pushes nodes apart, if it is larger than 0 it pulls them together. struct ForceManyBody { - /// Whether the force is enabled. + /// Whether the many body force is enabled. + /// + /// The many body force is applied on each pair of nodes in a way that ressembles an electrical charge. If the + /// strength is smaller than 0, it pushes nodes apart; if it is larger than 0, it pulls them together. std::optional enabled; /// The strength of the force. @@ -40,7 +43,10 @@ namespace rerun::blueprint::archetypes { ForceManyBody() = default; ForceManyBody(ForceManyBody&& other) = default; - /// Whether the force is enabled. + /// Whether the many body force is enabled. + /// + /// The many body force is applied on each pair of nodes in a way that ressembles an electrical charge. If the + /// strength is smaller than 0, it pushes nodes apart; if it is larger than 0, it pulls them together. ForceManyBody with_enabled(rerun::blueprint::components::Enabled _enabled) && { enabled = std::move(_enabled); // See: https://github.com/rerun-io/rerun/issues/4027 diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/force_position.hpp b/rerun_cpp/src/rerun/blueprint/archetypes/force_position.hpp index 36d740ce7393..3c6fbf9d266b 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/force_position.hpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/force_position.hpp @@ -20,7 +20,9 @@ namespace rerun::blueprint::archetypes { /// **Archetype**: Similar to gravity, this force pulls nodes towards a specific position. struct ForcePosition { - /// Whether the force is enabled. + /// Whether the position force is enabled. + /// + /// The position force pulls nodes towards a specific position, similar to gravity. std::optional enabled; /// The strength of the force. @@ -40,7 +42,9 @@ namespace rerun::blueprint::archetypes { ForcePosition() = default; ForcePosition(ForcePosition&& other) = default; - /// Whether the force is enabled. + /// Whether the position force is enabled. + /// + /// The position force pulls nodes towards a specific position, similar to gravity. ForcePosition with_enabled(rerun::blueprint::components::Enabled _enabled) && { enabled = std::move(_enabled); // See: https://github.com/rerun-io/rerun/issues/4027 diff --git a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/force_center.py b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/force_center.py index 7d026c887d70..5804b3c0db7f 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/force_center.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/force_center.py @@ -32,7 +32,9 @@ def __init__( Parameters ---------- enabled: - Whether the force is enabled. + Whether the center force is enabled. + + The center force tries to move the center of mass of the graph towards the origin. strength: The strength of the force. @@ -63,7 +65,9 @@ def _clear(cls) -> ForceCenter: default=None, converter=blueprint_components.EnabledBatch._optional, # type: ignore[misc] ) - # Whether the force is enabled. + # Whether the center force is enabled. + # + # The center force tries to move the center of mass of the graph towards the origin. # # (Docstring intentionally commented out to hide this field from the docs) diff --git a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/force_collision_radius.py b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/force_collision_radius.py index 80464759b93f..169c8f5e7ba0 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/force_collision_radius.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/force_collision_radius.py @@ -21,7 +21,7 @@ @define(str=False, repr=False, init=False) class ForceCollisionRadius(Archetype): - """**Archetype**: Resolves collisions between the bounding spheres, according to the radius of the nodes.""" + """**Archetype**: Resolves collisions between the bounding circles, according to the radius of the nodes.""" def __init__( self: Any, @@ -36,7 +36,9 @@ def __init__( Parameters ---------- enabled: - Whether the force is enabled. + Whether the collision force is enabled. + + The collision force resolves collisions between nodes based on the bounding circle defined by their radius. strength: The strength of the force. iterations: @@ -72,7 +74,9 @@ def _clear(cls) -> ForceCollisionRadius: default=None, converter=blueprint_components.EnabledBatch._optional, # type: ignore[misc] ) - # Whether the force is enabled. + # Whether the collision force is enabled. + # + # The collision force resolves collisions between nodes based on the bounding circle defined by their radius. # # (Docstring intentionally commented out to hide this field from the docs) diff --git a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/force_link.py b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/force_link.py index bf24c7265d63..f3c179715a0a 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/force_link.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/force_link.py @@ -36,7 +36,9 @@ def __init__( Parameters ---------- enabled: - Whether the force is enabled. + Whether the link force is enabled. + + The link force aims to achieve a target distance between two nodes that are connected by one ore more edges. distance: The target distance between two nodes. iterations: @@ -72,7 +74,9 @@ def _clear(cls) -> ForceLink: default=None, converter=blueprint_components.EnabledBatch._optional, # type: ignore[misc] ) - # Whether the force is enabled. + # Whether the link force is enabled. + # + # The link force aims to achieve a target distance between two nodes that are connected by one ore more edges. # # (Docstring intentionally commented out to hide this field from the docs) diff --git a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/force_many_body.py b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/force_many_body.py index 4750ac834505..1881af385409 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/force_many_body.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/force_many_body.py @@ -36,7 +36,10 @@ def __init__( Parameters ---------- enabled: - Whether the force is enabled. + Whether the many body force is enabled. + + The many body force is applied on each pair of nodes in a way that ressembles an electrical charge. If the + strength is smaller than 0, it pushes nodes apart; if it is larger than 0, it pulls them together. strength: The strength of the force. @@ -69,7 +72,10 @@ def _clear(cls) -> ForceManyBody: default=None, converter=blueprint_components.EnabledBatch._optional, # type: ignore[misc] ) - # Whether the force is enabled. + # Whether the many body force is enabled. + # + # The many body force is applied on each pair of nodes in a way that ressembles an electrical charge. If the + # strength is smaller than 0, it pushes nodes apart; if it is larger than 0, it pulls them together. # # (Docstring intentionally commented out to hide this field from the docs) diff --git a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/force_position.py b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/force_position.py index 61e63623c9c2..aa83eb92516d 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/force_position.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/force_position.py @@ -36,7 +36,9 @@ def __init__( Parameters ---------- enabled: - Whether the force is enabled. + Whether the position force is enabled. + + The position force pulls nodes towards a specific position, similar to gravity. strength: The strength of the force. position: @@ -70,7 +72,9 @@ def _clear(cls) -> ForcePosition: default=None, converter=blueprint_components.EnabledBatch._optional, # type: ignore[misc] ) - # Whether the force is enabled. + # Whether the position force is enabled. + # + # The position force pulls nodes towards a specific position, similar to gravity. # # (Docstring intentionally commented out to hide this field from the docs) From 49fb94fa25a2466ec597baa7531949d64482c41b Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Tue, 17 Dec 2024 12:43:54 +0100 Subject: [PATCH 03/30] Fix ui radius crashing graph view (#8502) --- crates/viewer/re_view_graph/src/visualizers/nodes.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/crates/viewer/re_view_graph/src/visualizers/nodes.rs b/crates/viewer/re_view_graph/src/visualizers/nodes.rs index 2d7c1f0176da..b03a0c3121f6 100644 --- a/crates/viewer/re_view_graph/src/visualizers/nodes.rs +++ b/crates/viewer/re_view_graph/src/visualizers/nodes.rs @@ -3,7 +3,6 @@ use re_chunk::LatestAtQuery; use re_log_types::{EntityPath, Instance}; use re_query::{clamped_zip_2x4, range_zip_1x4}; use re_types::components::{Color, Radius, ShowLabels}; -use re_types::datatypes::Float32; use re_types::{ self, archetypes, components::{self}, @@ -23,6 +22,8 @@ pub struct NodeVisualizer { pub data: ahash::HashMap, } +pub const FALLBACK_RADIUS: f32 = 4.0; + /// The label information of a [`re_types::archetypes::GraphNodes`]. #[derive(Clone)] pub enum Label { @@ -120,7 +121,8 @@ impl VisualizerSystem for NodeVisualizer { color, }, _ => Label::Circle { - radius: radius.unwrap_or(4.0), + // Radius is negative for UI radii, but we don't handle this here. + radius: radius.unwrap_or(FALLBACK_RADIUS).abs(), color, }, }; @@ -160,7 +162,7 @@ impl TypedComponentFallbackProvider for NodeVisualizer { impl TypedComponentFallbackProvider for NodeVisualizer { fn fallback_for(&self, _ctx: &QueryContext<'_>) -> Radius { - Radius(Float32(4.0f32)) + FALLBACK_RADIUS.into() } } From d5d0d4c0642db3a1c1253345b16fb98a2288661c Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Tue, 17 Dec 2024 14:00:14 +0100 Subject: [PATCH 04/30] Update egui to the commit before 0.30.0 (#8506) Make sure we test everything that went into 0.30.0, while we wait for * https://github.com/lampsitter/egui_commonmark/pull/69 --- Cargo.lock | 25 +++++++++++++------------ Cargo.toml | 14 +++++++------- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5500cc0e61f3..951fba200727 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1934,7 +1934,7 @@ checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" [[package]] name = "ecolor" version = "0.29.1" -source = "git+https://github.com/emilk/egui.git?rev=0823a36952a6791a0e28e6e8eac4f35639ab3091#0823a36952a6791a0e28e6e8eac4f35639ab3091" +source = "git+https://github.com/emilk/egui.git?rev=0fb340fe89e9476b2fec15c2eff1405e51e5c04e#0fb340fe89e9476b2fec15c2eff1405e51e5c04e" dependencies = [ "bytemuck", "color-hex", @@ -1951,7 +1951,7 @@ checksum = "18aade80d5e09429040243ce1143ddc08a92d7a22820ac512610410a4dd5214f" [[package]] name = "eframe" version = "0.29.1" -source = "git+https://github.com/emilk/egui.git?rev=0823a36952a6791a0e28e6e8eac4f35639ab3091#0823a36952a6791a0e28e6e8eac4f35639ab3091" +source = "git+https://github.com/emilk/egui.git?rev=0fb340fe89e9476b2fec15c2eff1405e51e5c04e#0fb340fe89e9476b2fec15c2eff1405e51e5c04e" dependencies = [ "ahash", "bytemuck", @@ -1990,7 +1990,7 @@ dependencies = [ [[package]] name = "egui" version = "0.29.1" -source = "git+https://github.com/emilk/egui.git?rev=0823a36952a6791a0e28e6e8eac4f35639ab3091#0823a36952a6791a0e28e6e8eac4f35639ab3091" +source = "git+https://github.com/emilk/egui.git?rev=0fb340fe89e9476b2fec15c2eff1405e51e5c04e#0fb340fe89e9476b2fec15c2eff1405e51e5c04e" dependencies = [ "accesskit", "ahash", @@ -2007,7 +2007,7 @@ dependencies = [ [[package]] name = "egui-wgpu" version = "0.29.1" -source = "git+https://github.com/emilk/egui.git?rev=0823a36952a6791a0e28e6e8eac4f35639ab3091#0823a36952a6791a0e28e6e8eac4f35639ab3091" +source = "git+https://github.com/emilk/egui.git?rev=0fb340fe89e9476b2fec15c2eff1405e51e5c04e#0fb340fe89e9476b2fec15c2eff1405e51e5c04e" dependencies = [ "ahash", "bytemuck", @@ -2026,7 +2026,7 @@ dependencies = [ [[package]] name = "egui-winit" version = "0.29.1" -source = "git+https://github.com/emilk/egui.git?rev=0823a36952a6791a0e28e6e8eac4f35639ab3091#0823a36952a6791a0e28e6e8eac4f35639ab3091" +source = "git+https://github.com/emilk/egui.git?rev=0fb340fe89e9476b2fec15c2eff1405e51e5c04e#0fb340fe89e9476b2fec15c2eff1405e51e5c04e" dependencies = [ "accesskit_winit", "ahash", @@ -2068,7 +2068,7 @@ dependencies = [ [[package]] name = "egui_extras" version = "0.29.1" -source = "git+https://github.com/emilk/egui.git?rev=0823a36952a6791a0e28e6e8eac4f35639ab3091#0823a36952a6791a0e28e6e8eac4f35639ab3091" +source = "git+https://github.com/emilk/egui.git?rev=0fb340fe89e9476b2fec15c2eff1405e51e5c04e#0fb340fe89e9476b2fec15c2eff1405e51e5c04e" dependencies = [ "ahash", "egui", @@ -2085,7 +2085,7 @@ dependencies = [ [[package]] name = "egui_glow" version = "0.29.1" -source = "git+https://github.com/emilk/egui.git?rev=0823a36952a6791a0e28e6e8eac4f35639ab3091#0823a36952a6791a0e28e6e8eac4f35639ab3091" +source = "git+https://github.com/emilk/egui.git?rev=0fb340fe89e9476b2fec15c2eff1405e51e5c04e#0fb340fe89e9476b2fec15c2eff1405e51e5c04e" dependencies = [ "ahash", "bytemuck", @@ -2102,7 +2102,7 @@ dependencies = [ [[package]] name = "egui_kittest" version = "0.29.1" -source = "git+https://github.com/emilk/egui.git?rev=0823a36952a6791a0e28e6e8eac4f35639ab3091#0823a36952a6791a0e28e6e8eac4f35639ab3091" +source = "git+https://github.com/emilk/egui.git?rev=0fb340fe89e9476b2fec15c2eff1405e51e5c04e#0fb340fe89e9476b2fec15c2eff1405e51e5c04e" dependencies = [ "dify", "egui", @@ -2171,7 +2171,7 @@ checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "emath" version = "0.29.1" -source = "git+https://github.com/emilk/egui.git?rev=0823a36952a6791a0e28e6e8eac4f35639ab3091#0823a36952a6791a0e28e6e8eac4f35639ab3091" +source = "git+https://github.com/emilk/egui.git?rev=0fb340fe89e9476b2fec15c2eff1405e51e5c04e#0fb340fe89e9476b2fec15c2eff1405e51e5c04e" dependencies = [ "bytemuck", "serde", @@ -2287,7 +2287,7 @@ dependencies = [ [[package]] name = "epaint" version = "0.29.1" -source = "git+https://github.com/emilk/egui.git?rev=0823a36952a6791a0e28e6e8eac4f35639ab3091#0823a36952a6791a0e28e6e8eac4f35639ab3091" +source = "git+https://github.com/emilk/egui.git?rev=0fb340fe89e9476b2fec15c2eff1405e51e5c04e#0fb340fe89e9476b2fec15c2eff1405e51e5c04e" dependencies = [ "ab_glyph", "ahash", @@ -2306,7 +2306,7 @@ dependencies = [ [[package]] name = "epaint_default_fonts" version = "0.29.1" -source = "git+https://github.com/emilk/egui.git?rev=0823a36952a6791a0e28e6e8eac4f35639ab3091#0823a36952a6791a0e28e6e8eac4f35639ab3091" +source = "git+https://github.com/emilk/egui.git?rev=0fb340fe89e9476b2fec15c2eff1405e51e5c04e#0fb340fe89e9476b2fec15c2eff1405e51e5c04e" [[package]] name = "equivalent" @@ -3731,7 +3731,8 @@ checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" [[package]] name = "kittest" version = "0.1.0" -source = "git+https://github.com/rerun-io/kittest?branch=main#06e01f17fed36a997e1541f37b2d47e3771d7533" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f659954571a3c132356bd15c25f0dcf14d270a28ec5c58797adc2f432831bed5" dependencies = [ "accesskit", "accesskit_consumer 0.25.0", diff --git a/Cargo.toml b/Cargo.toml index 39f77691d90b..8a8b7a28d3e9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -554,13 +554,13 @@ significant_drop_tightening = "allow" # An update of parking_lot made this trigg # As a last resport, patch with a commit to our own repository. # ALWAYS document what PR the commit hash is part of, or when it was merged into the upstream trunk. -ecolor = { git = "https://github.com/emilk/egui.git", rev = "0823a36952a6791a0e28e6e8eac4f35639ab3091" } # egui master 2024-12-16 15:08 -eframe = { git = "https://github.com/emilk/egui.git", rev = "0823a36952a6791a0e28e6e8eac4f35639ab3091" } # egui master 2024-12-16 15:08 -egui = { git = "https://github.com/emilk/egui.git", rev = "0823a36952a6791a0e28e6e8eac4f35639ab3091" } # egui master 2024-12-16 15:08 -egui_extras = { git = "https://github.com/emilk/egui.git", rev = "0823a36952a6791a0e28e6e8eac4f35639ab3091" } # egui master 2024-12-16 15:08 -egui_kittest = { git = "https://github.com/emilk/egui.git", rev = "0823a36952a6791a0e28e6e8eac4f35639ab3091" } # egui master 2024-12-16 15:08 -egui-wgpu = { git = "https://github.com/emilk/egui.git", rev = "0823a36952a6791a0e28e6e8eac4f35639ab3091" } # egui master 2024-12-16 15:08 -emath = { git = "https://github.com/emilk/egui.git", rev = "0823a36952a6791a0e28e6e8eac4f35639ab3091" } # egui master 2024-12-16 15:08 +ecolor = { git = "https://github.com/emilk/egui.git", rev = "0fb340fe89e9476b2fec15c2eff1405e51e5c04e" } # egui master 2024-12-16 just pre 0.30.0 release +eframe = { git = "https://github.com/emilk/egui.git", rev = "0fb340fe89e9476b2fec15c2eff1405e51e5c04e" } # egui master 2024-12-16 just pre 0.30.0 release +egui = { git = "https://github.com/emilk/egui.git", rev = "0fb340fe89e9476b2fec15c2eff1405e51e5c04e" } # egui master 2024-12-16 just pre 0.30.0 release +egui_extras = { git = "https://github.com/emilk/egui.git", rev = "0fb340fe89e9476b2fec15c2eff1405e51e5c04e" } # egui master 2024-12-16 just pre 0.30.0 release +egui_kittest = { git = "https://github.com/emilk/egui.git", rev = "0fb340fe89e9476b2fec15c2eff1405e51e5c04e" } # egui master 2024-12-16 just pre 0.30.0 release +egui-wgpu = { git = "https://github.com/emilk/egui.git", rev = "0fb340fe89e9476b2fec15c2eff1405e51e5c04e" } # egui master 2024-12-16 just pre 0.30.0 release +emath = { git = "https://github.com/emilk/egui.git", rev = "0fb340fe89e9476b2fec15c2eff1405e51e5c04e" } # egui master 2024-12-16 just pre 0.30.0 release # Useful while developing: # ecolor = { path = "../../egui/crates/ecolor" } From cd524ea21b0bd8b9a635401886deccca53125a3e Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Tue, 17 Dec 2024 15:04:38 +0100 Subject: [PATCH 05/30] Fix graph node hover (#8508) * no hover at all * no highlight on non-text box nodes --- crates/viewer/re_view_graph/src/ui/draw.rs | 7 +++++++ crates/viewer/re_view_graph/src/view.rs | 4 +++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/crates/viewer/re_view_graph/src/ui/draw.rs b/crates/viewer/re_view_graph/src/ui/draw.rs index 4122377be478..bc6f30e285ea 100644 --- a/crates/viewer/re_view_graph/src/ui/draw.rs +++ b/crates/viewer/re_view_graph/src/ui/draw.rs @@ -130,6 +130,13 @@ fn draw_circle_label( Color32::TRANSPARENT, Stroke::new(2.0, visuals.selection.stroke.color), ); + } else if highlight.hover == HoverHighlight::Hovered { + painter.circle( + resp.rect.center(), + radius - 2.0, + Color32::TRANSPARENT, + Stroke::new(2.0, visuals.widgets.hovered.bg_fill), + ); } resp diff --git a/crates/viewer/re_view_graph/src/view.rs b/crates/viewer/re_view_graph/src/view.rs index 3bef101d01c3..11b08183f761 100644 --- a/crates/viewer/re_view_graph/src/view.rs +++ b/crates/viewer/re_view_graph/src/view.rs @@ -200,7 +200,9 @@ Display a graph of nodes and edges. } }); - if resp.hovered() { + // Don't set the view to hovered if something else was already hovered. + // (this can only mean that a graph node/edge was hovered) + if resp.hovered() && ctx.selection_state().hovered_items().is_empty() { ctx.selection_state().set_hovered(Item::View(query.view_id)); } From 0a5fe0873042f40eaf7f3e714d65df7b50876f17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jochen=20G=C3=B6rtler?= Date: Tue, 17 Dec 2024 15:30:49 +0100 Subject: [PATCH 06/30] Fix setting fallback `Position2D` and geometry improvements (#8505) ### Related * Closes #8503. ### What This fixes setting the fallback value in the selection panel. It also deals with geometry that can't be drawn in a meaningful way because of that. --- .../re_view_graph/src/layout/provider.rs | 42 +++++++++++++------ .../release_checklist/check_graph_view.py | 11 +++++ 2 files changed, 40 insertions(+), 13 deletions(-) diff --git a/crates/viewer/re_view_graph/src/layout/provider.rs b/crates/viewer/re_view_graph/src/layout/provider.rs index b49f3f6669a0..d9c718d29146 100644 --- a/crates/viewer/re_view_graph/src/layout/provider.rs +++ b/crates/viewer/re_view_graph/src/layout/provider.rs @@ -139,13 +139,17 @@ impl ForceLayoutProvider { layout: &Layout, params: &ForceLayoutParams, ) -> Self { - let nodes = request.all_nodes().map(|(id, v)| { - if let Some(rect) = layout.get_node(&id) { - let pos = rect.center(); - fj::Node::from(v).position(pos.x as f64, pos.y as f64) - } else { - fj::Node::from(v) + let nodes = request.all_nodes().map(|(id, template)| { + let node = fj::Node::from(template); + + if template.fixed_position.is_none() { + if let Some(rect) = layout.get_node(&id) { + let pos = rect.center(); + return node.position(pos.x as f64, pos.y as f64); + } } + + node }); let radii = request .all_nodes() @@ -207,13 +211,17 @@ impl ForceLayoutProvider { target: edge.target, }) .or_default(); - geometries.push(EdgeGeometry { - target_arrow, - path: line_segment( - layout.nodes[&edge.source], - layout.nodes[&edge.target], - ), - }); + + let source = layout.nodes[&edge.source]; + let target = layout.nodes[&edge.target]; + + // We only draw edges if they can be displayed meaningfully. + if source.center() != target.center() && !source.intersects(target) { + geometries.push(EdgeGeometry { + target_arrow, + path: line_segment(source, target), + }); + } } else { // Multiple edges occupy the same space, so we fan them out. let num_edges = edges.len(); @@ -222,6 +230,14 @@ impl ForceLayoutProvider { let source_rect = layout.nodes[slot_source]; let target_rect = layout.nodes[slot_target]; + if source_rect.center() == target_rect.center() + || source_rect.intersects(target_rect) + { + // There is no meaningful geometry to draw here. + // Keep in mind that self-edges are handled separately above. + continue; + } + let d = (target_rect.center() - source_rect.center()).normalized(); let source_pos = source_rect.intersects_ray_from_center(d); diff --git a/tests/python/release_checklist/check_graph_view.py b/tests/python/release_checklist/check_graph_view.py index 97e9964394bd..27ae31d839c4 100644 --- a/tests/python/release_checklist/check_graph_view.py +++ b/tests/python/release_checklist/check_graph_view.py @@ -15,6 +15,7 @@ * `graph` has directed edges, while `graph2` has undirected edges. * `graph` and `graph2` are shown in two different viewers. * There is a third viewer, `Both`, that shows both `graph` and `graph2` in the same viewer. +* The `coincident` viewer shows two nodes, `A` and `B`, at the same position """ @@ -22,6 +23,10 @@ def log_readme() -> None: rr.log("readme", rr.TextDocument(README, media_type=rr.MediaType.MARKDOWN), static=True) +def log_coincident_nodes() -> None: + rr.log("coincident", rr.GraphNodes(["A", "B"], labels=["A", "B"], positions=[[-150, 0], [150, 0]])) + + def log_graphs() -> None: DATA = [ ("A", None), @@ -51,6 +56,7 @@ def run(args: Namespace) -> None: log_readme() log_graphs() + log_coincident_nodes() rr.send_blueprint( rrb.Blueprint( @@ -58,6 +64,11 @@ def run(args: Namespace) -> None: rrb.GraphView(origin="graph", name="Graph 1"), rrb.GraphView(origin="graph2", name="Graph 2"), rrb.GraphView(name="Both", contents=["/graph", "/graph2"]), + rrb.GraphView( + origin="coincident", + name="Coincident nodes", + overrides={"coincident": [rr.components.Position2D([0, 0])]}, + ), rrb.TextDocumentView(origin="readme", name="Instructions"), ) ) From 57b45e7162a9c4f07cc2da0da3416f6cf7783697 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Tue, 17 Dec 2024 16:58:13 +0100 Subject: [PATCH 07/30] Hide outline rectangle around views (#8507) * Closes https://github.com/rerun-io/rerun/issues/8494 Removes the highlighted rectangle around views that are hovered or selected. Why? Because we already have the tab title for this. Keeps it for containers, because they have no tab title. https://github.com/user-attachments/assets/bb407161-f3a8-4c66-bbd9-816f8dd28561 --- crates/viewer/re_viewport/src/viewport_ui.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/crates/viewer/re_viewport/src/viewport_ui.rs b/crates/viewer/re_viewport/src/viewport_ui.rs index ad4d3a005480..602c57a7f67b 100644 --- a/crates/viewer/re_viewport/src/viewport_ui.rs +++ b/crates/viewer/re_viewport/src/viewport_ui.rs @@ -165,6 +165,13 @@ impl ViewportUi { continue; }; + if matches!(contents, Contents::View(_)) + && !should_display_drop_destination_frame + { + // We already light up the view tab title; that is enough + continue; + } + // We want the rectangle to be on top of everything in the viewport, // including stuff in "zoom-pan areas", like we use in the graph view. let top_layer_id = From 75c6f146c89a9543a37c56cf61fc275b543891e7 Mon Sep 17 00:00:00 2001 From: Antoine Beyeler <49431240+abey79@users.noreply.github.com> Date: Tue, 17 Dec 2024 17:41:11 +0100 Subject: [PATCH 08/30] Fix the event count in the static-over-temporal error message (#8513) Regression introduced in #6934 and caught by `check_static_components_ui` Before: ![image](https://github.com/user-attachments/assets/b06bea44-ae51-4989-a3a2-eb4f4a7e1bc0) After: ![image](https://github.com/user-attachments/assets/1250995a-6ae8-42ad-90c9-aee42234ff4f) --- crates/store/re_chunk_store/src/stats.rs | 20 ++++++++++++++++++++ crates/viewer/re_data_ui/src/component.rs | 3 +-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/crates/store/re_chunk_store/src/stats.rs b/crates/store/re_chunk_store/src/stats.rs index 1f281b8179be..213d946b9b23 100644 --- a/crates/store/re_chunk_store/src/stats.rs +++ b/crates/store/re_chunk_store/src/stats.rs @@ -320,4 +320,24 @@ impl ChunkStore { .sum() }) } + + /// Returns the number of temporal events logged for an entity for a specific component on all timelines. + /// + /// This ignores static events. + pub fn num_temporal_events_for_component_on_all_timelines( + &self, + entity_path: &EntityPath, + component_name: ComponentName, + ) -> u64 { + self.all_timelines() + .iter() + .map(|timeline| { + self.num_temporal_events_for_component_on_timeline( + timeline, + entity_path, + component_name, + ) + }) + .sum() + } } diff --git a/crates/viewer/re_data_ui/src/component.rs b/crates/viewer/re_data_ui/src/component.rs index eeab5dabdbf0..663923ddb5cd 100644 --- a/crates/viewer/re_data_ui/src/component.rs +++ b/crates/viewer/re_data_ui/src/component.rs @@ -75,8 +75,7 @@ impl DataUi for ComponentPathLatestAtResults<'_> { let temporal_message_count = engine .store() - .num_temporal_events_for_component_on_timeline( - &query.timeline(), + .num_temporal_events_for_component_on_all_timelines( entity_path, *component_name, ); From 7a19d102bfeb3b132432741b58f39c58b2ae65d1 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Tue, 17 Dec 2024 17:53:57 +0100 Subject: [PATCH 09/30] Fix Plane3D component ui when it's non-editable (#8509) * Fixes https://github.com/rerun-io/rerun/issues/8488 Shows normal always as a vec now ![image](https://github.com/user-attachments/assets/b23a1437-bc67-4054-abc3-04d3a7fa973f) Editable one is unchanged (we'd need more space for edit boxes, so we rely on multiline ui): ![image](https://github.com/user-attachments/assets/ebf0b8e6-c116-49f4-be99-10731e9c99b8) --- crates/viewer/re_component_ui/src/plane3d.rs | 62 +++++++++++--------- 1 file changed, 33 insertions(+), 29 deletions(-) diff --git a/crates/viewer/re_component_ui/src/plane3d.rs b/crates/viewer/re_component_ui/src/plane3d.rs index 2b3484f60e19..d0432dd7a4a2 100644 --- a/crates/viewer/re_component_ui/src/plane3d.rs +++ b/crates/viewer/re_component_ui/src/plane3d.rs @@ -83,37 +83,41 @@ pub fn edit_or_view_plane3d( let distance = value.distance(); ui.label("n"); - // Show simplified combobox if this is axis aligned. - let mut axis_dir = AxisDirection::from(glam::Vec3::from(value.normal())); - let normal_response = response_with_changes_of_inner( - egui::ComboBox::from_id_salt("plane_normal") - .selected_text(format!("{axis_dir}")) - .height(250.0) - .show_ui(ui, |ui| { - let mut variants = AxisDirection::VARIANTS.iter(); - #[allow(clippy::unwrap_used)] // We know there's more than zero variants. - let variant = variants.next().unwrap(); - - let mut response = - ui.selectable_value(&mut axis_dir, *variant, variant.to_string()); - for variant in variants { - response |= ui.selectable_value(&mut axis_dir, *variant, variant.to_string()); - } - - if let MaybeMutRef::MutRef(value) = value { + + let normal_response = if let Some(value_mut) = value.as_mut() { + // Show simplified combobox if this is axis aligned. + let mut axis_dir = AxisDirection::from(glam::Vec3::from(value_mut.normal())); + response_with_changes_of_inner( + egui::ComboBox::from_id_salt("plane_normal") + .selected_text(format!("{axis_dir}")) + .height(250.0) + .show_ui(ui, |ui| { + let mut variants = AxisDirection::VARIANTS.iter(); + #[allow(clippy::unwrap_used)] // We know there's more than zero variants. + let variant = variants.next().unwrap(); + + let mut response = + ui.selectable_value(&mut axis_dir, *variant, variant.to_string()); + for variant in variants { + response |= + ui.selectable_value(&mut axis_dir, *variant, variant.to_string()); + } if let Ok(new_dir) = glam::Vec3::try_from(axis_dir) { - **value = components::Plane3D::new(new_dir, distance); + *value_mut = components::Plane3D::new(new_dir, distance); } - } - response - }), - ) - .on_hover_text(format!( - "{} {} {}", - re_format::format_f32(value.normal().x()), - re_format::format_f32(value.normal().y()), - re_format::format_f32(value.normal().z()), - )); + response + }), + ) + .on_hover_text(format!( + "{} {} {}", + re_format::format_f32(value.normal().x()), + re_format::format_f32(value.normal().y()), + re_format::format_f32(value.normal().z()), + )) + } else { + let normal = value.normal(); + edit_or_view_vec3d_raw(ui, &mut MaybeMutRef::Ref(&normal)) + }; ui.label("d"); let mut maybe_mut_distance = match value { From 13b56d789e1b6db381d7c273c54ed19a63e2c415 Mon Sep 17 00:00:00 2001 From: Clement Rey Date: Tue, 17 Dec 2024 17:59:58 +0100 Subject: [PATCH 10/30] Fix missing `ComponentBatchCow` export in public lib (#8515) Title. --- crates/top/re_sdk/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/top/re_sdk/src/lib.rs b/crates/top/re_sdk/src/lib.rs index ebb46e4ef346..2ef51e0e1dd7 100644 --- a/crates/top/re_sdk/src/lib.rs +++ b/crates/top/re_sdk/src/lib.rs @@ -91,7 +91,7 @@ pub mod time { pub use time::{Time, TimePoint, Timeline}; pub use re_types_core::{ - Archetype, ArchetypeName, AsComponents, Component, ComponentBatch, + Archetype, ArchetypeName, AsComponents, Component, ComponentBatch, ComponentBatchCow, ComponentBatchCowWithDescriptor, ComponentDescriptor, ComponentName, DatatypeName, DeserializationError, DeserializationResult, GenericIndicatorComponent, Loggable, LoggableBatch, NamedIndicatorComponent, SerializationError, SerializationResult, SizeBytes, From 5a5e2b5a46e12284976c6d669ac83eb088b972fb Mon Sep 17 00:00:00 2001 From: Clement Rey Date: Tue, 17 Dec 2024 18:25:00 +0100 Subject: [PATCH 11/30] egui 0.30 (#8516) Title. --- Cargo.lock | 304 ++++++++++-------- Cargo.toml | 40 +-- .../re_component_ui/src/marker_shape.rs | 2 +- 3 files changed, 189 insertions(+), 157 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 951fba200727..60076725fe56 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -38,7 +38,7 @@ dependencies = [ "accesskit_consumer 0.26.0", "atspi-common", "serde", - "thiserror", + "thiserror 1.0.65", "zvariant", ] @@ -187,7 +187,7 @@ dependencies = [ "ndk-context", "ndk-sys 0.6.0+11769913", "num_enum", - "thiserror", + "thiserror 1.0.65", ] [[package]] @@ -318,7 +318,7 @@ dependencies = [ "argh_shared", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -691,7 +691,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -731,7 +731,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -748,7 +748,7 @@ checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -854,7 +854,7 @@ dependencies = [ "num-derive", "num-rational", "num-traits", - "thiserror", + "thiserror 1.0.65", ] [[package]] @@ -1066,7 +1066,7 @@ checksum = "bcfcc3cd946cb52f0bbfdbbcfa2f4e24f75ebb6c0e1002f7c25904fada18b9ec" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -1108,7 +1108,7 @@ dependencies = [ "sha2", "ssri", "tempfile", - "thiserror", + "thiserror 1.0.65", "tokio", "tokio-stream", "walkdir", @@ -1125,7 +1125,7 @@ dependencies = [ "polling", "rustix", "slab", - "thiserror", + "thiserror 1.0.65", ] [[package]] @@ -1156,7 +1156,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03fa8484a7f2eef80e6dd2e2be90b322b9c29aeb1bbc206013d6eb2104db7241" dependencies = [ "serde", - "thiserror", + "thiserror 1.0.65", "toml", ] @@ -1205,7 +1205,7 @@ dependencies = [ "semver", "serde", "serde_json", - "thiserror", + "thiserror 1.0.65", ] [[package]] @@ -1321,7 +1321,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "696283b40e1a39d208ee614b92e5f6521d16962edeb47c48372585ec92419943" dependencies = [ - "thiserror", + "thiserror 1.0.65", ] [[package]] @@ -1355,7 +1355,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -1768,7 +1768,7 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -1779,7 +1779,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -1877,7 +1877,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -1933,8 +1933,9 @@ checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" [[package]] name = "ecolor" -version = "0.29.1" -source = "git+https://github.com/emilk/egui.git?rev=0fb340fe89e9476b2fec15c2eff1405e51e5c04e#0fb340fe89e9476b2fec15c2eff1405e51e5c04e" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d72e9c39f6e11a2e922d04a34ec5e7ef522ea3f5a1acfca7a19d16ad5fe50f5" dependencies = [ "bytemuck", "color-hex", @@ -1950,8 +1951,9 @@ checksum = "18aade80d5e09429040243ce1143ddc08a92d7a22820ac512610410a4dd5214f" [[package]] name = "eframe" -version = "0.29.1" -source = "git+https://github.com/emilk/egui.git?rev=0fb340fe89e9476b2fec15c2eff1405e51e5c04e#0fb340fe89e9476b2fec15c2eff1405e51e5c04e" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2f2d9e7ea2d11ec9e98a8683b6eb99f9d7d0448394ef6e0d6d91bd4eb817220" dependencies = [ "ahash", "bytemuck", @@ -1989,8 +1991,9 @@ dependencies = [ [[package]] name = "egui" -version = "0.29.1" -source = "git+https://github.com/emilk/egui.git?rev=0fb340fe89e9476b2fec15c2eff1405e51e5c04e#0fb340fe89e9476b2fec15c2eff1405e51e5c04e" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "252d52224d35be1535d7fd1d6139ce071fb42c9097773e79f7665604f5596b5e" dependencies = [ "accesskit", "ahash", @@ -2006,8 +2009,9 @@ dependencies = [ [[package]] name = "egui-wgpu" -version = "0.29.1" -source = "git+https://github.com/emilk/egui.git?rev=0fb340fe89e9476b2fec15c2eff1405e51e5c04e#0fb340fe89e9476b2fec15c2eff1405e51e5c04e" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26c1e821d2d8921ef6ce98b258c7e24d9d6aab2ca1f9cdf374eca997e7f67f59" dependencies = [ "ahash", "bytemuck", @@ -2016,7 +2020,7 @@ dependencies = [ "epaint", "log", "profiling", - "thiserror", + "thiserror 1.0.65", "type-map", "web-time", "wgpu", @@ -2025,8 +2029,9 @@ dependencies = [ [[package]] name = "egui-winit" -version = "0.29.1" -source = "git+https://github.com/emilk/egui.git?rev=0fb340fe89e9476b2fec15c2eff1405e51e5c04e#0fb340fe89e9476b2fec15c2eff1405e51e5c04e" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e84c2919cd9f3a38a91e8f84ac6a245c19251fd95226ed9fae61d5ea564fce3" dependencies = [ "accesskit_winit", "ahash", @@ -2044,9 +2049,9 @@ dependencies = [ [[package]] name = "egui_commonmark" -version = "0.18.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f169228b94d1c8eb9330b7ea1b5f65b1193b6bea95159c87f574ed4aff8c172" +checksum = "43d76bd08ab5264071aab3bd0ad0f5bdc34cf36cbb4be4c17c853a935c84d5fe" dependencies = [ "egui", "egui_commonmark_backend", @@ -2056,9 +2061,9 @@ dependencies = [ [[package]] name = "egui_commonmark_backend" -version = "0.18.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcd08f95abeb137e59c9bfdd0880d362bff74a83afe13805fde7a2d014ef773d" +checksum = "47acd9dde83a575127a498e4ef77b00377f85c258ae259214bb125c79efefd00" dependencies = [ "egui", "egui_extras", @@ -2067,8 +2072,9 @@ dependencies = [ [[package]] name = "egui_extras" -version = "0.29.1" -source = "git+https://github.com/emilk/egui.git?rev=0fb340fe89e9476b2fec15c2eff1405e51e5c04e#0fb340fe89e9476b2fec15c2eff1405e51e5c04e" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7a8198c088b1007108cb2d403bc99a5e370999b200db4f14559610d7330126" dependencies = [ "ahash", "egui", @@ -2084,8 +2090,9 @@ dependencies = [ [[package]] name = "egui_glow" -version = "0.29.1" -source = "git+https://github.com/emilk/egui.git?rev=0fb340fe89e9476b2fec15c2eff1405e51e5c04e#0fb340fe89e9476b2fec15c2eff1405e51e5c04e" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3eaf6264cc7608e3e69a7d57a6175f438275f1b3889c1a551b418277721c95e6" dependencies = [ "ahash", "bytemuck", @@ -2101,8 +2108,9 @@ dependencies = [ [[package]] name = "egui_kittest" -version = "0.29.1" -source = "git+https://github.com/emilk/egui.git?rev=0fb340fe89e9476b2fec15c2eff1405e51e5c04e#0fb340fe89e9476b2fec15c2eff1405e51e5c04e" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27fe1ba792adf7a7bd8c51852d2dfa2a1711aea05bc532f9aa5f54a15533d33e" dependencies = [ "dify", "egui", @@ -2114,9 +2122,9 @@ dependencies = [ [[package]] name = "egui_plot" -version = "0.29.0" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8dca4871c15d51aadb79534dcf51a8189e5de3426ee7b465eb7db9a0a81ea67" +checksum = "c226cae80a6ee10c4d3aaf9e33bd9e9b2f1c0116b6036bdc2a1cfc9d2d0dcc10" dependencies = [ "ahash", "egui", @@ -2125,9 +2133,9 @@ dependencies = [ [[package]] name = "egui_table" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ef148ce13d97a23376b92d3c5d0dddedd98c28b17053ceb326b31b92ea45d07" +checksum = "dc957dce337da3794d73f0c20a998e205850ed8a0fa1410432bddf31133667f8" dependencies = [ "egui", "serde", @@ -2136,8 +2144,9 @@ dependencies = [ [[package]] name = "egui_tiles" -version = "0.10.1" -source = "git+https://github.com/rerun-io/egui_tiles?rev=48e0ef566479000a23d8dabf84badced98f1b9a6#48e0ef566479000a23d8dabf84badced98f1b9a6" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "588dcf9028464fb4d23baf1f7805c13927fb540f2f9096f7d177b814848645a3" dependencies = [ "ahash", "egui", @@ -2170,8 +2179,9 @@ checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "emath" -version = "0.29.1" -source = "git+https://github.com/emilk/egui.git?rev=0fb340fe89e9476b2fec15c2eff1405e51e5c04e#0fb340fe89e9476b2fec15c2eff1405e51e5c04e" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4fe73c1207b864ee40aa0b0c038d6092af1030744678c60188a05c28553515d" dependencies = [ "bytemuck", "serde", @@ -2216,7 +2226,7 @@ checksum = "f282cfdfe92516eb26c2af8589c274c7c17681f5ecc03c18255fe741c6aa64eb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -2237,7 +2247,7 @@ checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -2248,7 +2258,7 @@ checksum = "2f9ed6b3789237c8a0c1c505af1c7eb2c560df6186f01b098c3a1064ea532f38" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -2269,7 +2279,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -2286,8 +2296,9 @@ dependencies = [ [[package]] name = "epaint" -version = "0.29.1" -source = "git+https://github.com/emilk/egui.git?rev=0fb340fe89e9476b2fec15c2eff1405e51e5c04e#0fb340fe89e9476b2fec15c2eff1405e51e5c04e" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5666f8d25236293c966fbb3635eac18b04ad1914e3bab55bc7d44b9980cafcac" dependencies = [ "ab_glyph", "ahash", @@ -2305,8 +2316,9 @@ dependencies = [ [[package]] name = "epaint_default_fonts" -version = "0.29.1" -source = "git+https://github.com/emilk/egui.git?rev=0fb340fe89e9476b2fec15c2eff1405e51e5c04e#0fb340fe89e9476b2fec15c2eff1405e51e5c04e" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66f6ddac3e6ac6fd4c3d48bb8b1943472f8da0f43a4303bcd8a18aa594401c80" [[package]] name = "equivalent" @@ -2514,7 +2526,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -2616,7 +2628,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -2794,7 +2806,7 @@ dependencies = [ "inflections", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -3440,7 +3452,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -3676,7 +3688,7 @@ dependencies = [ "combine", "jni-sys", "log", - "thiserror", + "thiserror 1.0.65", "walkdir", "windows-sys 0.45.0", ] @@ -4076,7 +4088,7 @@ checksum = "59bb584eaeeab6bd0226ccf3509a69d7936d148cf3d036ad350abe35e8c6856e" dependencies = [ "miette-derive", "once_cell", - "thiserror", + "thiserror 1.0.65", "unicode-width", ] @@ -4088,7 +4100,7 @@ checksum = "49e7bc1560b95a3c4a25d03de42fe76ca718ab92d1a22a55b9b4cf67b3ae635c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -4213,7 +4225,7 @@ dependencies = [ "rustc-hash 1.1.0", "spirv", "termcolor", - "thiserror", + "thiserror 1.0.65", "unicode-xid", ] @@ -4270,7 +4282,7 @@ dependencies = [ "ndk-sys 0.6.0+11769913", "num_enum", "raw-window-handle", - "thiserror", + "thiserror 1.0.65", ] [[package]] @@ -4397,7 +4409,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -4460,7 +4472,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -4929,7 +4941,7 @@ checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -5111,7 +5123,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" dependencies = [ "proc-macro2", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -5149,7 +5161,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a65f2e60fbf1063868558d69c6beacf412dc755f9fc020f514b7955fc914fe30" dependencies = [ "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -5179,7 +5191,7 @@ dependencies = [ "prost", "prost-types", "regex", - "syn 2.0.85", + "syn 2.0.87", "tempfile", ] @@ -5193,7 +5205,7 @@ dependencies = [ "itertools 0.13.0", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -5314,7 +5326,7 @@ dependencies = [ "proc-macro2", "pyo3-macros-backend", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -5327,7 +5339,7 @@ dependencies = [ "proc-macro2", "pyo3-build-config", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -5363,7 +5375,7 @@ dependencies = [ "rustc-hash 2.0.0", "rustls 0.23.18", "socket2", - "thiserror", + "thiserror 1.0.65", "tokio", "tracing", ] @@ -5380,7 +5392,7 @@ dependencies = [ "rustc-hash 2.0.0", "rustls 0.23.18", "slab", - "thiserror", + "thiserror 1.0.65", "tinyvec", "tracing", ] @@ -5519,7 +5531,7 @@ dependencies = [ "serde", "serde_json", "sha2", - "thiserror", + "thiserror 1.0.65", "time", "url", "uuid", @@ -5635,7 +5647,7 @@ dependencies = [ "re_types_core", "serde", "similar-asserts", - "thiserror", + "thiserror 1.0.65", ] [[package]] @@ -5665,7 +5677,7 @@ dependencies = [ "re_types", "re_types_core", "similar-asserts", - "thiserror", + "thiserror 1.0.65", "tinyvec", "web-time", ] @@ -5762,7 +5774,7 @@ dependencies = [ "re_tracing", "re_types", "tempfile", - "thiserror", + "thiserror 1.0.65", "uuid", "walkdir", ] @@ -5895,7 +5907,7 @@ dependencies = [ "re_types_core", "serde", "similar-asserts", - "thiserror", + "thiserror 1.0.65", "web-time", ] @@ -5935,7 +5947,7 @@ dependencies = [ "re_protos", "re_smart_channel", "re_types", - "thiserror", + "thiserror 1.0.65", "tokio", "tokio-stream", "tonic", @@ -5989,7 +6001,7 @@ dependencies = [ "re_types", "rmp-serde", "serde_test", - "thiserror", + "thiserror 1.0.65", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", @@ -6028,7 +6040,7 @@ dependencies = [ "serde_bytes", "similar-asserts", "static_assertions", - "thiserror", + "thiserror 1.0.65", "time", "typenum", "uuid", @@ -6077,7 +6089,7 @@ dependencies = [ "num-rational", "serde", "serde_json", - "thiserror", + "thiserror 1.0.65", ] [[package]] @@ -6085,7 +6097,7 @@ name = "re_protos" version = "0.21.0-alpha.1+dev" dependencies = [ "prost", - "thiserror", + "thiserror 1.0.65", "tonic", "tonic-web-wasm-client", ] @@ -6128,7 +6140,7 @@ dependencies = [ "re_types_core", "seq-macro", "similar-asserts", - "thiserror", + "thiserror 1.0.65", ] [[package]] @@ -6192,7 +6204,7 @@ dependencies = [ "slotmap", "smallvec", "static_assertions", - "thiserror", + "thiserror 1.0.65", "tinystl", "tobj", "type-map", @@ -6261,7 +6273,7 @@ dependencies = [ "re_web_viewer_server", "re_ws_comms", "similar-asserts", - "thiserror", + "thiserror 1.0.65", "webbrowser", ] @@ -6278,7 +6290,7 @@ dependencies = [ "re_log_encoding", "re_log_types", "re_smart_channel", - "thiserror", + "thiserror 1.0.65", ] [[package]] @@ -6422,7 +6434,7 @@ dependencies = [ "serde", "similar-asserts", "smallvec", - "thiserror", + "thiserror 1.0.65", "uuid", ] @@ -6450,7 +6462,7 @@ dependencies = [ "re_tracing", "rust-format", "serde", - "syn 2.0.85", + "syn 2.0.87", "tempfile", "toml", "unindent", @@ -6479,7 +6491,7 @@ dependencies = [ "re_tuid", "serde", "smallvec", - "thiserror", + "thiserror 1.0.65", ] [[package]] @@ -6531,7 +6543,7 @@ dependencies = [ "re_rav1d", "re_tracing", "serde", - "thiserror", + "thiserror 1.0.65", "wasm-bindgen", "web-sys", ] @@ -6599,7 +6611,7 @@ dependencies = [ "re_ui", "re_viewer_context", "re_viewport_blueprint", - "thiserror", + "thiserror 1.0.65", ] [[package]] @@ -6689,7 +6701,7 @@ dependencies = [ "re_viewport_blueprint", "serde", "smallvec", - "thiserror", + "thiserror 1.0.65", "vec1", "web-time", ] @@ -6714,7 +6726,7 @@ dependencies = [ "re_view", "re_viewer_context", "re_viewport_blueprint", - "thiserror", + "thiserror 1.0.65", "wgpu", ] @@ -6844,7 +6856,7 @@ dependencies = [ "serde_json", "strum", "strum_macros", - "thiserror", + "thiserror 1.0.65", "uuid", "wasm-bindgen", "wasm-bindgen-futures", @@ -6903,7 +6915,7 @@ dependencies = [ "slotmap", "smallvec", "strum_macros", - "thiserror", + "thiserror 1.0.65", "uuid", "wasm-bindgen-futures", "wgpu", @@ -6955,7 +6967,7 @@ dependencies = [ "re_viewer_context", "slotmap", "smallvec", - "thiserror", + "thiserror 1.0.65", ] [[package]] @@ -6965,7 +6977,7 @@ dependencies = [ "document-features", "re_analytics", "re_log", - "thiserror", + "thiserror 1.0.65", "tiny_http", ] @@ -6985,7 +6997,7 @@ dependencies = [ "re_memory", "re_smart_channel", "re_tracing", - "thiserror", + "thiserror 1.0.65", "tungstenite", ] @@ -7015,7 +7027,7 @@ checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ "getrandom", "libredox", - "thiserror", + "thiserror 1.0.65", ] [[package]] @@ -7163,7 +7175,7 @@ dependencies = [ "reqwest 0.11.27", "serde", "task-local-extensions", - "thiserror", + "thiserror 1.0.65", ] [[package]] @@ -7641,7 +7653,7 @@ dependencies = [ "cargo-manifest", "cargo_metadata 0.18.1", "serde", - "thiserror", + "thiserror 1.0.65", "toml", "tracing", ] @@ -7880,7 +7892,7 @@ checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -7903,7 +7915,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -8108,7 +8120,7 @@ dependencies = [ "log", "memmap2 0.9.5", "rustix", - "thiserror", + "thiserror 1.0.65", "wayland-backend", "wayland-client", "wayland-csd-frame", @@ -8220,7 +8232,7 @@ dependencies = [ "serde", "sha-1", "sha2", - "thiserror", + "thiserror 1.0.65", "xxhash-rust", ] @@ -8277,7 +8289,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -8315,9 +8327,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.85" +version = "2.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56" +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" dependencies = [ "proc-macro2", "quote", @@ -8347,7 +8359,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -8498,7 +8510,16 @@ version = "1.0.65" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d11abd9594d9b38965ef50805c5e469ca9cc6f197f883f717e0269a3057b3d5" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.65", +] + +[[package]] +name = "thiserror" +version = "2.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93605438cbd668185516ab499d589afb7ee1859ea3d5fc8f6b0755e1c7443767" +dependencies = [ + "thiserror-impl 2.0.7", ] [[package]] @@ -8509,7 +8530,18 @@ checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d8749b4531af2117677a5fcd12b1348a3fe2b81e36e61ffeac5c4aa3273e36" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", ] [[package]] @@ -8698,7 +8730,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -8822,7 +8854,7 @@ dependencies = [ "prost-build", "prost-types", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -8841,7 +8873,7 @@ dependencies = [ "httparse", "js-sys", "pin-project", - "thiserror", + "thiserror 1.0.65", "tonic", "tower-service", "wasm-bindgen", @@ -8916,7 +8948,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -8956,7 +8988,7 @@ dependencies = [ "rustls 0.23.18", "rustls-pki-types", "sha1", - "thiserror", + "thiserror 1.0.65", "utf-8", "webpki-roots 0.26.6", ] @@ -9187,9 +9219,9 @@ dependencies = [ [[package]] name = "walkers" -version = "0.29.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0688ad9bfb3bd49d997a6fb831e9ef21e251f4698c07e2f9902dcdb72d254bd" +checksum = "70ca9bf7f5ff8a6d57de654d06fb25e5c6d60e0acc7e938d6fc15324b8e22a2f" dependencies = [ "egui", "egui_extras", @@ -9201,7 +9233,7 @@ dependencies = [ "lru", "reqwest 0.11.27", "reqwest-middleware", - "thiserror", + "thiserror 2.0.7", "tokio", "wasm-bindgen-futures", ] @@ -9231,7 +9263,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -9271,7 +9303,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", "wasm-bindgen-shared", ] @@ -9339,7 +9371,7 @@ checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -9646,7 +9678,7 @@ dependencies = [ "raw-window-handle", "rustc-hash 1.1.0", "smallvec", - "thiserror", + "thiserror 1.0.65", "wgpu-hal", "wgpu-types", ] @@ -9685,7 +9717,7 @@ dependencies = [ "renderdoc-sys", "rustc-hash 1.1.0", "smallvec", - "thiserror", + "thiserror 1.0.65", "wasm-bindgen", "web-sys", "wgpu-types", @@ -9784,7 +9816,7 @@ checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -9795,7 +9827,7 @@ checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -10244,7 +10276,7 @@ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", "synstructure", ] @@ -10304,7 +10336,7 @@ checksum = "709ab20fc57cb22af85be7b360239563209258430bccf38d8b979c5a2ae3ecce" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", "zbus-lockstep", "zbus_xml", "zvariant", @@ -10319,7 +10351,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", "zvariant_utils", ] @@ -10365,7 +10397,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -10385,7 +10417,7 @@ checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", "synstructure", ] @@ -10414,7 +10446,7 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -10467,7 +10499,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", "zvariant_utils", ] @@ -10479,5 +10511,5 @@ checksum = "c51bcff7cc3dbb5055396bcf774748c3dab426b4b8659046963523cee4808340" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] diff --git a/Cargo.toml b/Cargo.toml index 8a8b7a28d3e9..25af7569328a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -124,27 +124,27 @@ dav1d = { package = "re_rav1d", version = "0.1.3", default-features = false } # dav1d = { version = "0.10.3" } # Requires separate install of `dav1d` library. Fast in debug builds. Useful for development. # egui-crates: -ecolor = "0.29.1" -eframe = { version = "0.29.1", default-features = false, features = [ +ecolor = "0.30.0" +eframe = { version = "0.30.0", default-features = false, features = [ "accesskit", "default_fonts", "wayland", "x11", ] } -egui = { version = "0.29.1", features = [ +egui = { version = "0.30.0", features = [ "callstack", "color-hex", "log", "rayon", ] } -egui_commonmark = { version = "0.18", default-features = false } -egui_extras = { version = "0.29.1", features = ["http", "image", "serde"] } -egui_kittest = { version = "0.29.1", features = ["wgpu", "snapshot"] } -egui_plot = "0.29.0" # https://github.com/emilk/egui_plot -egui_table = "0.1.0" # https://github.com/rerun-io/egui_table -egui_tiles = "0.10.1" # https://github.com/rerun-io/egui_tiles -egui-wgpu = "0.29.1" -emath = "0.29.1" +egui_commonmark = { version = "0.19", default-features = false } +egui_extras = { version = "0.30.0", features = ["http", "image", "serde"] } +egui_kittest = { version = "0.30.0", features = ["wgpu", "snapshot"] } +egui_plot = "0.30.0" # https://github.com/emilk/egui_plot +egui_table = "0.2.0" # https://github.com/rerun-io/egui_table +egui_tiles = "0.11.0" # https://github.com/rerun-io/egui_tiles +egui-wgpu = "0.30.0" +emath = "0.30.0" # All of our direct external dependencies should be found here: ahash = "0.8" @@ -293,7 +293,7 @@ url = "2.3" uuid = "1.1" vec1 = "1.8" walkdir = "2.0" -walkers = "0.29" +walkers = "0.32" # NOTE: `rerun_js/web-viewer/build-wasm.mjs` is HIGHLY sensitive to changes in `wasm-bindgen`. # Whenever updating `wasm-bindgen`, update this and the narrower dependency specifications in # `crates/viewer/re_viewer/Cargo.toml`, and make sure that the build script still works. @@ -554,13 +554,13 @@ significant_drop_tightening = "allow" # An update of parking_lot made this trigg # As a last resport, patch with a commit to our own repository. # ALWAYS document what PR the commit hash is part of, or when it was merged into the upstream trunk. -ecolor = { git = "https://github.com/emilk/egui.git", rev = "0fb340fe89e9476b2fec15c2eff1405e51e5c04e" } # egui master 2024-12-16 just pre 0.30.0 release -eframe = { git = "https://github.com/emilk/egui.git", rev = "0fb340fe89e9476b2fec15c2eff1405e51e5c04e" } # egui master 2024-12-16 just pre 0.30.0 release -egui = { git = "https://github.com/emilk/egui.git", rev = "0fb340fe89e9476b2fec15c2eff1405e51e5c04e" } # egui master 2024-12-16 just pre 0.30.0 release -egui_extras = { git = "https://github.com/emilk/egui.git", rev = "0fb340fe89e9476b2fec15c2eff1405e51e5c04e" } # egui master 2024-12-16 just pre 0.30.0 release -egui_kittest = { git = "https://github.com/emilk/egui.git", rev = "0fb340fe89e9476b2fec15c2eff1405e51e5c04e" } # egui master 2024-12-16 just pre 0.30.0 release -egui-wgpu = { git = "https://github.com/emilk/egui.git", rev = "0fb340fe89e9476b2fec15c2eff1405e51e5c04e" } # egui master 2024-12-16 just pre 0.30.0 release -emath = { git = "https://github.com/emilk/egui.git", rev = "0fb340fe89e9476b2fec15c2eff1405e51e5c04e" } # egui master 2024-12-16 just pre 0.30.0 release +# ecolor = { git = "https://github.com/emilk/egui.git", rev = "0fb340fe89e9476b2fec15c2eff1405e51e5c04e" } # egui master 2024-12-16 just pre 0.30.0 release +# eframe = { git = "https://github.com/emilk/egui.git", rev = "0fb340fe89e9476b2fec15c2eff1405e51e5c04e" } # egui master 2024-12-16 just pre 0.30.0 release +# egui = { git = "https://github.com/emilk/egui.git", rev = "0fb340fe89e9476b2fec15c2eff1405e51e5c04e" } # egui master 2024-12-16 just pre 0.30.0 release +# egui_extras = { git = "https://github.com/emilk/egui.git", rev = "0fb340fe89e9476b2fec15c2eff1405e51e5c04e" } # egui master 2024-12-16 just pre 0.30.0 release +# egui_kittest = { git = "https://github.com/emilk/egui.git", rev = "0fb340fe89e9476b2fec15c2eff1405e51e5c04e" } # egui master 2024-12-16 just pre 0.30.0 release +# egui-wgpu = { git = "https://github.com/emilk/egui.git", rev = "0fb340fe89e9476b2fec15c2eff1405e51e5c04e" } # egui master 2024-12-16 just pre 0.30.0 release +# emath = { git = "https://github.com/emilk/egui.git", rev = "0fb340fe89e9476b2fec15c2eff1405e51e5c04e" } # egui master 2024-12-16 just pre 0.30.0 release # Useful while developing: # ecolor = { path = "../../egui/crates/ecolor" } @@ -574,7 +574,7 @@ emath = { git = "https://github.com/emilk/egui.git", rev = "0fb340fe89e9476b2fec # egui_plot = { git = "https://github.com/emilk/egui_plot.git", rev = "1f6ae49a5f6bf43a869c215dea0d3028be8d742a" } # egui_plot = { path = "../../egui_plot/egui_plot" } -egui_tiles = { git = "https://github.com/rerun-io/egui_tiles", rev = "48e0ef566479000a23d8dabf84badced98f1b9a6" } # https://github.com/rerun-io/egui_tiles/pull/89 2024-11-19 +# egui_tiles = { git = "https://github.com/rerun-io/egui_tiles", rev = "48e0ef566479000a23d8dabf84badced98f1b9a6" } # https://github.com/rerun-io/egui_tiles/pull/89 2024-11-19 #egui_tiles = { path = "../egui_tiles" } # egui_commonmark = { git = "https://github.com/rerun-io/egui_commonmark", rev = "7a9dc755bfa351a3796274cb8ca87129b051c084" } # https://github.com/lampsitter/egui_commonmark/pull/65 diff --git a/crates/viewer/re_component_ui/src/marker_shape.rs b/crates/viewer/re_component_ui/src/marker_shape.rs index 5c08682ee1f4..92ceaa4245e4 100644 --- a/crates/viewer/re_component_ui/src/marker_shape.rs +++ b/crates/viewer/re_component_ui/src/marker_shape.rs @@ -81,7 +81,7 @@ pub(crate) fn paint_marker( .filled(true); let bounds = egui_plot::PlotBounds::new_symmetrical(0.5); - let transform = egui_plot::PlotTransform::new(rect, bounds, true, true); + let transform = egui_plot::PlotTransform::new(rect, bounds, [true, true].into()); let mut shapes = vec![]; points.shapes(ui, &transform, &mut shapes); From 06fed3db111fe3bd958e2cd4a9bcbeddf1d037fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jochen=20G=C3=B6rtler?= Date: Tue, 17 Dec 2024 18:28:08 +0100 Subject: [PATCH 12/30] Fix graph view node highlight on hover (#8512) ### What This fixes a problem introduced by #8495 that was only partially fixed by #8508, with graph view highlights flickering (ping-ponging) in the blueprint view. --- crates/viewer/re_view_graph/src/ui/draw.rs | 14 +++++++------- crates/viewer/re_view_graph/src/view.rs | 19 +++++++++++++++---- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/crates/viewer/re_view_graph/src/ui/draw.rs b/crates/viewer/re_view_graph/src/ui/draw.rs index bc6f30e285ea..ad58886a3761 100644 --- a/crates/viewer/re_view_graph/src/ui/draw.rs +++ b/crates/viewer/re_view_graph/src/ui/draw.rs @@ -330,6 +330,7 @@ pub fn draw_graph( layout: &Layout, query: &ViewQuery<'_>, lod: LevelOfDetail, + hover_click_item: &mut Option<(Item, Response)>, ) -> Rect { let entity_path = graph.entity(); let entity_highlights = query.highlights.entity_highlight(entity_path.hash()); @@ -363,19 +364,18 @@ pub fn draw_graph( }); }); - ctx.handle_select_hover_drag_interactions( - &response, - Item::DataResult(query.view_id, instance_path.clone()), - false, - ); - - // double click selects the entire entity + // Warning! The order is very important here. if response.double_clicked() { // Select the entire entity ctx.selection_state().set_selection(Item::DataResult( query.view_id, instance_path.entity_path.clone().into(), )); + } else if response.hovered() || response.clicked() { + *hover_click_item = Some(( + Item::DataResult(query.view_id, instance_path.clone()), + response.clone(), + )); } response diff --git a/crates/viewer/re_view_graph/src/view.rs b/crates/viewer/re_view_graph/src/view.rs index 11b08183f761..b7ecf8b0d91e 100644 --- a/crates/viewer/re_view_graph/src/view.rs +++ b/crates/viewer/re_view_graph/src/view.rs @@ -1,3 +1,4 @@ +use egui::Response; use re_log_types::EntityPath; use re_types::{ blueprint::{ @@ -191,18 +192,28 @@ Display a graph of nodes and edges. let level_of_detail = LevelOfDetail::from_scaling(ui_from_world.scaling); + let mut hover_click_item: Option<(Item, Response)> = None; + let resp = zoom_pan_area(ui, &mut ui_from_world, |ui| { let mut world_bounding_rect = egui::Rect::NOTHING; for graph in &graphs { - let graph_rect = draw_graph(ui, ctx, graph, layout, query, level_of_detail); + let graph_rect = draw_graph( + ui, + ctx, + graph, + layout, + query, + level_of_detail, + &mut hover_click_item, + ); world_bounding_rect = world_bounding_rect.union(graph_rect); } }); - // Don't set the view to hovered if something else was already hovered. - // (this can only mean that a graph node/edge was hovered) - if resp.hovered() && ctx.selection_state().hovered_items().is_empty() { + if let Some((item, response)) = hover_click_item { + ctx.handle_select_hover_drag_interactions(&response, item, false); + } else if resp.hovered() { ctx.selection_state().set_hovered(Item::View(query.view_id)); } From b1fe788bf0186d9b5763ceebd29a6f7e30a9139d Mon Sep 17 00:00:00 2001 From: Clement Rey Date: Tue, 17 Dec 2024 18:30:22 +0100 Subject: [PATCH 13/30] Fix broken doc test (#8517) This broke `cargo t --all --all-features`, which is not run on CI, hence why it doesn't show up there. --- crates/top/rerun/src/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/top/rerun/src/lib.rs b/crates/top/rerun/src/lib.rs index 486e96a4ae7a..c96f194d11a6 100644 --- a/crates/top/rerun/src/lib.rs +++ b/crates/top/rerun/src/lib.rs @@ -81,12 +81,13 @@ //! You can buffer the log messages in memory and then show them in an embedded viewer: //! //! ```no_run +//! # let main_thread_token = re_capabilities::MainThreadToken::i_promise_i_am_on_the_main_thread(); //! # fn log_to(rec: &rerun::RecordingStream) {} //! let (rec, storage) = rerun::RecordingStreamBuilder::new("rerun_example_app").memory()?; //! log_to(&rec); //! //! // Will block program execution! -//! rerun::native_viewer::show(storage.take()); +//! rerun::native_viewer::show(main_thread_token, storage.take()); //! //! # Ok::<(), Box>(()) //! ``` From a040ce3ef13fc944dbbb0d2ad186a99e9dd0b7fd Mon Sep 17 00:00:00 2001 From: Antoine Beyeler <49431240+abey79@users.noreply.github.com> Date: Tue, 17 Dec 2024 22:53:06 +0100 Subject: [PATCH 14/30] Make all checklists force activate their blueprints (#8520) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ☝🏻 This ensure a clean blueprint slate for checklists without having to `rerun reset` --------- Co-authored-by: Clement Rey --- tests/python/release_checklist/README.md | 6 - .../release_checklist/check_1d_tensor_data.py | 2 + .../check_all_components_ui.py | 2 + .../release_checklist/check_annotations.py | 2 + tests/python/release_checklist/check_bgr.py | 3 +- .../check_blueprint_bw_compat.py | 9 +- .../check_blueprint_overrides.py | 39 +++--- .../check_chroma_subsampling.py | 3 +- .../check_colormap_edit_ui.py | 3 +- .../check_component_and_transform_clamping.py | 3 +- .../check_container_hierarchy.py | 2 + ...ntext_menu_add_entity_to_new_space_view.py | 3 +- .../check_context_menu_collapse_expand_all.py | 3 +- ...heck_context_menu_invalid_sub_container.py | 3 +- .../check_context_menu_multi_selection.py | 3 +- .../check_context_menu_single_selection.py | 3 +- ...xt_menu_single_selection_blueprint_tree.py | 3 +- .../check_context_menu_suggested_origin.py | 3 +- .../check_deselect_on_escape.py | 2 + .../check_drag_and_drop_selection.py | 3 +- .../release_checklist/check_draw_order.py | 10 +- .../check_entity_drag_and_drop.py | 3 +- tests/python/release_checklist/check_focus.py | 3 +- .../release_checklist/check_graph_view.py | 26 ++-- .../check_graph_view_multi_self_edges.py | 22 ++-- .../release_checklist/check_heuristics_2d.py | 2 + .../check_heuristics_mixed_2d_and_3d.py | 2 + .../check_heuristics_mixed_all_root.py | 2 + .../check_hover_select_reset.py | 2 + .../check_latest_at_partial_updates.py | 6 +- .../check_modal_scrolling.py | 6 +- .../check_mono_entity_views.py | 3 +- .../release_checklist/check_notebook.py | 2 +- .../check_out_of_tree_data_results.py | 3 +- .../release_checklist/check_overrides_2d.py | 113 +++++++++--------- .../check_parallelism_caching_reentrancy.py | 3 +- .../release_checklist/check_plot_overrides.py | 2 + .../check_range_partial_updates.py | 6 +- .../release_checklist/check_rbl_import.py | 9 +- .../release_checklist/check_scalar_clears.py | 2 + .../check_static_components_ui.py | 2 + .../check_static_override.py | 2 + .../check_transform3d_hierarchy.py | 9 +- .../python/release_checklist/check_version.py | 2 + tests/python/release_checklist/check_video.py | 23 ++-- 45 files changed, 197 insertions(+), 168 deletions(-) diff --git a/tests/python/release_checklist/README.md b/tests/python/release_checklist/README.md index ec710d70a2cf..d41559405ab9 100644 --- a/tests/python/release_checklist/README.md +++ b/tests/python/release_checklist/README.md @@ -3,12 +3,6 @@ # Interactive release checklist Welcome to the release checklist. -_**⚠ Make sure to clean your blueprints if you want to start from a clean slate ⚠**_ - -``` -pixi run rerun reset -``` - Run the testlist with: ``` pixi run -e examples python tests/python/release_checklist/main.py diff --git a/tests/python/release_checklist/check_1d_tensor_data.py b/tests/python/release_checklist/check_1d_tensor_data.py index ae418182e979..2e7aa43ad5cc 100644 --- a/tests/python/release_checklist/check_1d_tensor_data.py +++ b/tests/python/release_checklist/check_1d_tensor_data.py @@ -50,6 +50,8 @@ def run(args: Namespace) -> None: log_readme() log_1d_data() + rr.send_blueprint(rr.blueprint.Blueprint(auto_layout=True, auto_views=True), make_active=True, make_default=True) + if __name__ == "__main__": import argparse diff --git a/tests/python/release_checklist/check_all_components_ui.py b/tests/python/release_checklist/check_all_components_ui.py index 0849f5983c8b..0885c5010ccc 100644 --- a/tests/python/release_checklist/check_all_components_ui.py +++ b/tests/python/release_checklist/check_all_components_ui.py @@ -299,6 +299,8 @@ def run(args: Namespace) -> None: log_readme() log_some_views() + rr.send_blueprint(rr.blueprint.Blueprint(auto_layout=True, auto_views=True), make_active=True, make_default=True) + if __name__ == "__main__": import argparse diff --git a/tests/python/release_checklist/check_annotations.py b/tests/python/release_checklist/check_annotations.py index 3e8ff3f8012b..a63db849ce91 100644 --- a/tests/python/release_checklist/check_annotations.py +++ b/tests/python/release_checklist/check_annotations.py @@ -55,6 +55,8 @@ def run(args: Namespace) -> None: log_readme() log_annotations() + rr.send_blueprint(rr.blueprint.Blueprint(auto_layout=True, auto_views=True), make_active=True, make_default=True) + if __name__ == "__main__": import argparse diff --git a/tests/python/release_checklist/check_bgr.py b/tests/python/release_checklist/check_bgr.py index f1316e5c0504..8011e6692ff9 100644 --- a/tests/python/release_checklist/check_bgr.py +++ b/tests/python/release_checklist/check_bgr.py @@ -75,7 +75,8 @@ def download_example_image_as_rgb() -> np.ndarray: def run(args: Namespace) -> None: - rr.script_setup(args, f"{os.path.basename(__file__)}", recording_id=uuid4(), default_blueprint=blueprint()) + rr.script_setup(args, f"{os.path.basename(__file__)}", recording_id=uuid4()) + rr.send_blueprint(blueprint(), make_active=True, make_default=True) sample_image_rgb_u8 = download_example_image_as_rgb() log_readme() diff --git a/tests/python/release_checklist/check_blueprint_bw_compat.py b/tests/python/release_checklist/check_blueprint_bw_compat.py index dabc4fff1e5d..ee67012b93f5 100644 --- a/tests/python/release_checklist/check_blueprint_bw_compat.py +++ b/tests/python/release_checklist/check_blueprint_bw_compat.py @@ -54,12 +54,9 @@ def log_readme() -> None: def run(args: Namespace) -> None: - rr.script_setup( - args, - f"{os.path.basename(__file__)}", - recording_id=uuid4(), - default_blueprint=rrb.Grid(rrb.TextDocumentView(origin="readme")), - ) + rr.script_setup(args, f"{os.path.basename(__file__)}", recording_id=uuid4()) + + rr.send_blueprint(rrb.Grid(rrb.TextDocumentView(origin="readme")), make_active=True, make_default=True) log_readme() diff --git a/tests/python/release_checklist/check_blueprint_overrides.py b/tests/python/release_checklist/check_blueprint_overrides.py index 8fe9f5a91f6e..d09472cf39f6 100644 --- a/tests/python/release_checklist/check_blueprint_overrides.py +++ b/tests/python/release_checklist/check_blueprint_overrides.py @@ -34,26 +34,6 @@ def log_plots() -> None: cos_of_t = cos(float(t) / 10.0) rr.log("plots/cos", rr.Scalar(cos_of_t)) - rr.send_blueprint( - rrb.Blueprint( - rrb.Grid( - rrb.TextDocumentView(origin="readme", name="Instructions"), - rrb.TimeSeriesView( - name="Plots", - defaults=[rr.components.Color([0, 0, 255])], - overrides={ - "plots/cos": [ - rrb.VisualizerOverrides("SeriesPoint"), - rr.components.Color([0, 255, 0]), - # TODDO(#6670): This should just be `rr.components.MarkerShape.Cross` - rr.components.MarkerShapeBatch("cross"), - ], - }, - ), - ) - ) - ) - def run(args: Namespace) -> None: rr.script_setup(args, f"{os.path.basename(__file__)}", recording_id=uuid4()) @@ -61,6 +41,25 @@ def run(args: Namespace) -> None: log_readme() log_plots() + blueprint = rrb.Blueprint( + rrb.Grid( + rrb.TextDocumentView(origin="readme", name="Instructions"), + rrb.TimeSeriesView( + name="Plots", + defaults=[rr.components.Color([0, 0, 255])], + overrides={ + "plots/cos": [ + rrb.VisualizerOverrides("SeriesPoint"), + rr.components.Color([0, 255, 0]), + # TODDO(#6670): This should just be `rr.components.MarkerShape.Cross` + rr.components.MarkerShapeBatch("cross"), + ], + }, + ), + ) + ) + rr.send_blueprint(blueprint, make_active=True, make_default=True) + if __name__ == "__main__": import argparse diff --git a/tests/python/release_checklist/check_chroma_subsampling.py b/tests/python/release_checklist/check_chroma_subsampling.py index c072c57a995e..cb321b1e1807 100644 --- a/tests/python/release_checklist/check_chroma_subsampling.py +++ b/tests/python/release_checklist/check_chroma_subsampling.py @@ -220,7 +220,8 @@ def log_data() -> None: def run(args: Namespace) -> None: - rr.script_setup(args, f"{os.path.basename(__file__)}", recording_id=uuid4(), default_blueprint=blueprint()) + rr.script_setup(args, f"{os.path.basename(__file__)}", recording_id=uuid4()) + rr.send_blueprint(blueprint(), make_active=True, make_default=True) log_readme() log_data() diff --git a/tests/python/release_checklist/check_colormap_edit_ui.py b/tests/python/release_checklist/check_colormap_edit_ui.py index 7d7279469cd7..f022c49cdafb 100644 --- a/tests/python/release_checklist/check_colormap_edit_ui.py +++ b/tests/python/release_checklist/check_colormap_edit_ui.py @@ -35,7 +35,8 @@ def blueprint() -> rrb.BlueprintLike: def run(args: Namespace) -> None: - rr.script_setup(args, f"{os.path.basename(__file__)}", recording_id=uuid4(), default_blueprint=blueprint()) + rr.script_setup(args, f"{os.path.basename(__file__)}", recording_id=uuid4()) + rr.send_blueprint(blueprint(), make_active=True, make_default=True) log_readme() log_depth_image() diff --git a/tests/python/release_checklist/check_component_and_transform_clamping.py b/tests/python/release_checklist/check_component_and_transform_clamping.py index cfabe06a2fb2..66f6c832d99b 100644 --- a/tests/python/release_checklist/check_component_and_transform_clamping.py +++ b/tests/python/release_checklist/check_component_and_transform_clamping.py @@ -73,7 +73,8 @@ def log_data() -> None: def run(args: Namespace) -> None: - rr.script_setup(args, f"{os.path.basename(__file__)}", recording_id=uuid4(), default_blueprint=blueprint()) + rr.script_setup(args, f"{os.path.basename(__file__)}", recording_id=uuid4()) + rr.send_blueprint(blueprint(), make_active=True, make_default=True) log_readme() log_data() diff --git a/tests/python/release_checklist/check_container_hierarchy.py b/tests/python/release_checklist/check_container_hierarchy.py index 90150e3c6514..b602b0a2c422 100644 --- a/tests/python/release_checklist/check_container_hierarchy.py +++ b/tests/python/release_checklist/check_container_hierarchy.py @@ -91,6 +91,8 @@ def run(args: Namespace) -> None: log_readme() log_some_views() + rr.send_blueprint(rr.blueprint.Blueprint(auto_layout=True, auto_views=True), make_active=True, make_default=True) + if __name__ == "__main__": import argparse diff --git a/tests/python/release_checklist/check_context_menu_add_entity_to_new_space_view.py b/tests/python/release_checklist/check_context_menu_add_entity_to_new_space_view.py index 2bd104a8927a..ee01607dcac6 100644 --- a/tests/python/release_checklist/check_context_menu_add_entity_to_new_space_view.py +++ b/tests/python/release_checklist/check_context_menu_add_entity_to_new_space_view.py @@ -58,7 +58,8 @@ def log_some_views() -> None: def run(args: Namespace) -> None: - rr.script_setup(args, f"{os.path.basename(__file__)}", recording_id=uuid4(), default_blueprint=blueprint()) + rr.script_setup(args, f"{os.path.basename(__file__)}", recording_id=uuid4()) + rr.send_blueprint(blueprint(), make_active=True, make_default=True) log_readme() log_some_views() diff --git a/tests/python/release_checklist/check_context_menu_collapse_expand_all.py b/tests/python/release_checklist/check_context_menu_collapse_expand_all.py index ee1d9d74ffa8..05d378b7e522 100644 --- a/tests/python/release_checklist/check_context_menu_collapse_expand_all.py +++ b/tests/python/release_checklist/check_context_menu_collapse_expand_all.py @@ -51,7 +51,8 @@ def log_some_views() -> None: def run(args: Namespace) -> None: - rr.script_setup(args, f"{os.path.basename(__file__)}", recording_id=uuid4(), default_blueprint=blueprint()) + rr.script_setup(args, f"{os.path.basename(__file__)}", recording_id=uuid4()) + rr.send_blueprint(blueprint(), make_active=True, make_default=True) log_readme() log_some_views() diff --git a/tests/python/release_checklist/check_context_menu_invalid_sub_container.py b/tests/python/release_checklist/check_context_menu_invalid_sub_container.py index 9a32db71f704..670f3118b68f 100644 --- a/tests/python/release_checklist/check_context_menu_invalid_sub_container.py +++ b/tests/python/release_checklist/check_context_menu_invalid_sub_container.py @@ -46,7 +46,8 @@ def log_some_views() -> None: def run(args: Namespace) -> None: - rr.script_setup(args, f"{os.path.basename(__file__)}", recording_id=uuid4(), default_blueprint=blueprint()) + rr.script_setup(args, f"{os.path.basename(__file__)}", recording_id=uuid4()) + rr.send_blueprint(blueprint(), make_active=True, make_default=True) log_readme() log_some_views() diff --git a/tests/python/release_checklist/check_context_menu_multi_selection.py b/tests/python/release_checklist/check_context_menu_multi_selection.py index 8864588a4fd4..7c42f59bbc8e 100644 --- a/tests/python/release_checklist/check_context_menu_multi_selection.py +++ b/tests/python/release_checklist/check_context_menu_multi_selection.py @@ -83,7 +83,8 @@ def log_some_views() -> None: def run(args: Namespace) -> None: - rr.script_setup(args, f"{os.path.basename(__file__)}", recording_id=uuid4(), default_blueprint=blueprint()) + rr.script_setup(args, f"{os.path.basename(__file__)}", recording_id=uuid4()) + rr.send_blueprint(blueprint(), make_active=True, make_default=True) log_readme() log_some_views() diff --git a/tests/python/release_checklist/check_context_menu_single_selection.py b/tests/python/release_checklist/check_context_menu_single_selection.py index 14f7d5180281..5b9a3a9aca54 100644 --- a/tests/python/release_checklist/check_context_menu_single_selection.py +++ b/tests/python/release_checklist/check_context_menu_single_selection.py @@ -109,7 +109,8 @@ def log_some_views() -> None: def run(args: Namespace) -> None: - rr.script_setup(args, f"{os.path.basename(__file__)}", recording_id=uuid4(), default_blueprint=blueprint()) + rr.script_setup(args, f"{os.path.basename(__file__)}", recording_id=uuid4()) + rr.send_blueprint(blueprint(), make_active=True, make_default=True) log_readme() log_some_views() diff --git a/tests/python/release_checklist/check_context_menu_single_selection_blueprint_tree.py b/tests/python/release_checklist/check_context_menu_single_selection_blueprint_tree.py index 4b5ab7a340f1..bcf310ca2fda 100644 --- a/tests/python/release_checklist/check_context_menu_single_selection_blueprint_tree.py +++ b/tests/python/release_checklist/check_context_menu_single_selection_blueprint_tree.py @@ -85,7 +85,8 @@ def log_some_views() -> None: def run(args: Namespace) -> None: - rr.script_setup(args, f"{os.path.basename(__file__)}", recording_id=uuid4(), default_blueprint=blueprint()) + rr.script_setup(args, f"{os.path.basename(__file__)}", recording_id=uuid4()) + rr.send_blueprint(blueprint(), make_active=True, make_default=True) log_readme() log_some_views() diff --git a/tests/python/release_checklist/check_context_menu_suggested_origin.py b/tests/python/release_checklist/check_context_menu_suggested_origin.py index 02c120940bdb..a0b4933f8def 100644 --- a/tests/python/release_checklist/check_context_menu_suggested_origin.py +++ b/tests/python/release_checklist/check_context_menu_suggested_origin.py @@ -76,7 +76,8 @@ def log_some_views() -> None: def run(args: Namespace) -> None: - rr.script_setup(args, f"{os.path.basename(__file__)}", recording_id=uuid4(), default_blueprint=blueprint()) + rr.script_setup(args, f"{os.path.basename(__file__)}", recording_id=uuid4()) + rr.send_blueprint(blueprint(), make_active=True, make_default=True) log_readme() log_some_views() diff --git a/tests/python/release_checklist/check_deselect_on_escape.py b/tests/python/release_checklist/check_deselect_on_escape.py index e74698bc9656..dd86cfeb7fa8 100644 --- a/tests/python/release_checklist/check_deselect_on_escape.py +++ b/tests/python/release_checklist/check_deselect_on_escape.py @@ -38,6 +38,8 @@ def run(args: Namespace) -> None: log_readme() log_some_data() + rr.send_blueprint(rr.blueprint.Blueprint(auto_layout=True, auto_views=True), make_active=True, make_default=True) + if __name__ == "__main__": import argparse diff --git a/tests/python/release_checklist/check_drag_and_drop_selection.py b/tests/python/release_checklist/check_drag_and_drop_selection.py index 2ca4d7ee9b82..1c1f90ce5fcc 100644 --- a/tests/python/release_checklist/check_drag_and_drop_selection.py +++ b/tests/python/release_checklist/check_drag_and_drop_selection.py @@ -63,7 +63,8 @@ def log_some_scalar_entities() -> None: def run(args: Namespace) -> None: - rr.script_setup(args, f"{os.path.basename(__file__)}", recording_id=uuid4(), default_blueprint=blueprint()) + rr.script_setup(args, f"{os.path.basename(__file__)}", recording_id=uuid4()) + rr.send_blueprint(blueprint(), make_active=True, make_default=True) log_readme() log_some_scalar_entities() diff --git a/tests/python/release_checklist/check_draw_order.py b/tests/python/release_checklist/check_draw_order.py index df6ed675cbd0..87e397d6bf48 100644 --- a/tests/python/release_checklist/check_draw_order.py +++ b/tests/python/release_checklist/check_draw_order.py @@ -71,11 +71,11 @@ def run_2d_layering() -> None: def run(args: Namespace) -> None: - rr.script_setup( - args, - f"{os.path.basename(__file__)}", - recording_id=uuid4(), - default_blueprint=rrb.Grid(rrb.Spatial2DView(origin="/"), rrb.TextDocumentView(origin="readme")), + rr.script_setup(args, f"{os.path.basename(__file__)}", recording_id=uuid4()) + rr.send_blueprint( + rrb.Blueprint(rrb.Grid(rrb.Spatial2DView(origin="/"), rrb.TextDocumentView(origin="readme"))), + make_active=True, + make_default=True, ) log_readme() diff --git a/tests/python/release_checklist/check_entity_drag_and_drop.py b/tests/python/release_checklist/check_entity_drag_and_drop.py index 0e9d718064dd..85439d8cf03b 100644 --- a/tests/python/release_checklist/check_entity_drag_and_drop.py +++ b/tests/python/release_checklist/check_entity_drag_and_drop.py @@ -79,7 +79,8 @@ def log_some_scalar_entities() -> None: def run(args: Namespace) -> None: - rr.script_setup(args, f"{os.path.basename(__file__)}", recording_id=uuid4(), default_blueprint=blueprint()) + rr.script_setup(args, f"{os.path.basename(__file__)}", recording_id=uuid4()) + rr.send_blueprint(blueprint(), make_active=True, make_default=True) log_readme() log_some_scalar_entities() diff --git a/tests/python/release_checklist/check_focus.py b/tests/python/release_checklist/check_focus.py index 91c25335f0e7..2bdbe82ce447 100644 --- a/tests/python/release_checklist/check_focus.py +++ b/tests/python/release_checklist/check_focus.py @@ -42,7 +42,8 @@ def log_some_views() -> None: def run(args: Namespace) -> None: - rr.script_setup(args, f"{os.path.basename(__file__)}", recording_id=uuid4(), default_blueprint=blueprint()) + rr.script_setup(args, f"{os.path.basename(__file__)}", recording_id=uuid4()) + rr.send_blueprint(blueprint(), make_active=True, make_default=True) log_readme() log_some_views() diff --git a/tests/python/release_checklist/check_graph_view.py b/tests/python/release_checklist/check_graph_view.py index 27ae31d839c4..4998792806e9 100644 --- a/tests/python/release_checklist/check_graph_view.py +++ b/tests/python/release_checklist/check_graph_view.py @@ -59,19 +59,19 @@ def run(args: Namespace) -> None: log_coincident_nodes() rr.send_blueprint( - rrb.Blueprint( - rrb.Grid( - rrb.GraphView(origin="graph", name="Graph 1"), - rrb.GraphView(origin="graph2", name="Graph 2"), - rrb.GraphView(name="Both", contents=["/graph", "/graph2"]), - rrb.GraphView( - origin="coincident", - name="Coincident nodes", - overrides={"coincident": [rr.components.Position2D([0, 0])]}, - ), - rrb.TextDocumentView(origin="readme", name="Instructions"), - ) - ) + rrb.Grid( + rrb.GraphView(origin="graph", name="Graph 1"), + rrb.GraphView(origin="graph2", name="Graph 2"), + rrb.GraphView(name="Both", contents=["/graph", "/graph2"]), + rrb.GraphView( + origin="coincident", + name="Coincident nodes", + overrides={"coincident": [rr.components.Position2D([0, 0])]}, + ), + rrb.TextDocumentView(origin="readme", name="Instructions"), + ), + make_default=True, + make_active=True, ) diff --git a/tests/python/release_checklist/check_graph_view_multi_self_edges.py b/tests/python/release_checklist/check_graph_view_multi_self_edges.py index 8b43cac93fc0..bef301ff7c23 100644 --- a/tests/python/release_checklist/check_graph_view_multi_self_edges.py +++ b/tests/python/release_checklist/check_graph_view_multi_self_edges.py @@ -55,17 +55,17 @@ def run(args: Namespace) -> None: log_readme() rr.send_blueprint( - rrb.Blueprint( - rrb.Grid( - rrb.GraphView(origin="graph", name="Multiple edges and self-edges"), - rrb.GraphView( - origin="graph", - name="Multiple edges and self-edges (without labels)", - defaults=[rr.components.ShowLabels(False)], - ), - rrb.TextDocumentView(origin="readme", name="Instructions"), - ) - ) + rrb.Grid( + rrb.GraphView(origin="graph", name="Multiple edges and self-edges"), + rrb.GraphView( + origin="graph", + name="Multiple edges and self-edges (without labels)", + defaults=[rr.components.ShowLabels(False)], + ), + rrb.TextDocumentView(origin="readme", name="Instructions"), + ), + make_active=True, + make_default=True, ) diff --git a/tests/python/release_checklist/check_heuristics_2d.py b/tests/python/release_checklist/check_heuristics_2d.py index a951d05bec2f..96549cbf06ea 100644 --- a/tests/python/release_checklist/check_heuristics_2d.py +++ b/tests/python/release_checklist/check_heuristics_2d.py @@ -70,6 +70,8 @@ def run(args: Namespace) -> None: log_readme() log_images() + rr.send_blueprint(rr.blueprint.Blueprint(auto_layout=True, auto_views=True), make_active=True, make_default=True) + if __name__ == "__main__": import argparse diff --git a/tests/python/release_checklist/check_heuristics_mixed_2d_and_3d.py b/tests/python/release_checklist/check_heuristics_mixed_2d_and_3d.py index ba151b266d41..18ee34985583 100644 --- a/tests/python/release_checklist/check_heuristics_mixed_2d_and_3d.py +++ b/tests/python/release_checklist/check_heuristics_mixed_2d_and_3d.py @@ -56,6 +56,8 @@ def run(args: Namespace) -> None: log_images() log_3d_scene() + rr.send_blueprint(rr.blueprint.Blueprint(auto_layout=True, auto_views=True), make_active=True, make_default=True) + if __name__ == "__main__": import argparse diff --git a/tests/python/release_checklist/check_heuristics_mixed_all_root.py b/tests/python/release_checklist/check_heuristics_mixed_all_root.py index 5b90b33e876a..38c2e1cbf12b 100644 --- a/tests/python/release_checklist/check_heuristics_mixed_all_root.py +++ b/tests/python/release_checklist/check_heuristics_mixed_all_root.py @@ -29,6 +29,8 @@ def run(args: Namespace) -> None: rr.log("points2d", rr.Points2D([[0, 0], [1, 1], [3, 2]], labels=["a", "b", "c"])) rr.log("readme", rr.TextDocument(README, media_type=rr.MediaType.MARKDOWN), timeless=True) + rr.send_blueprint(rr.blueprint.Blueprint(auto_layout=True, auto_views=True), make_active=True, make_default=True) + if __name__ == "__main__": import argparse diff --git a/tests/python/release_checklist/check_hover_select_reset.py b/tests/python/release_checklist/check_hover_select_reset.py index a83560ba7150..253949bb0c7d 100644 --- a/tests/python/release_checklist/check_hover_select_reset.py +++ b/tests/python/release_checklist/check_hover_select_reset.py @@ -108,6 +108,8 @@ def run(args: Namespace) -> None: log_graph() log_map() + rr.send_blueprint(rr.blueprint.Blueprint(auto_layout=True, auto_views=True), make_active=True, make_default=True) + if __name__ == "__main__": import argparse diff --git a/tests/python/release_checklist/check_latest_at_partial_updates.py b/tests/python/release_checklist/check_latest_at_partial_updates.py index 18d25bdbb82c..13bf39d61437 100644 --- a/tests/python/release_checklist/check_latest_at_partial_updates.py +++ b/tests/python/release_checklist/check_latest_at_partial_updates.py @@ -65,10 +65,6 @@ def blueprint() -> rrb.BlueprintLike: ), ] ), - # NOTE: It looks nice but it's very annoying when going through several checklists. - # rrb.BlueprintPanel(state="collapsed"), - # rrb.TimePanel(state="collapsed"), - # rrb.SelectionPanel(state="collapsed"), ) @@ -119,7 +115,7 @@ def log_points() -> None: def run(args: Namespace) -> None: rr.script_setup(args, f"{os.path.basename(__file__)}", recording_id=uuid4()) - rr.send_blueprint(blueprint()) + rr.send_blueprint(blueprint(), make_default=True, make_active=True) log_readme() log_points() diff --git a/tests/python/release_checklist/check_modal_scrolling.py b/tests/python/release_checklist/check_modal_scrolling.py index 8859f69acc17..bfb7e61df626 100644 --- a/tests/python/release_checklist/check_modal_scrolling.py +++ b/tests/python/release_checklist/check_modal_scrolling.py @@ -30,7 +30,11 @@ def run(args: Namespace) -> None: args, f"{os.path.basename(__file__)}", recording_id=uuid4(), - default_blueprint=rrb.Grid(rrb.Spatial2DView(origin="/"), rrb.TextDocumentView(origin="readme")), + ) + rr.send_blueprint( + rrb.Grid(rrb.Spatial2DView(origin="/"), rrb.TextDocumentView(origin="readme")), + make_active=True, + make_default=True, ) log_readme() diff --git a/tests/python/release_checklist/check_mono_entity_views.py b/tests/python/release_checklist/check_mono_entity_views.py index 90a45b40b821..b5c242635ee1 100644 --- a/tests/python/release_checklist/check_mono_entity_views.py +++ b/tests/python/release_checklist/check_mono_entity_views.py @@ -44,7 +44,8 @@ def blueprint() -> rrb.BlueprintLike: def run(args: Namespace) -> None: - rr.script_setup(args, f"{os.path.basename(__file__)}", recording_id=uuid4(), default_blueprint=blueprint()) + rr.script_setup(args, f"{os.path.basename(__file__)}", recording_id=uuid4()) + rr.send_blueprint(blueprint(), make_active=True, make_default=True) log_readme() log_data() diff --git a/tests/python/release_checklist/check_notebook.py b/tests/python/release_checklist/check_notebook.py index 978acd0c2932..42612295067d 100644 --- a/tests/python/release_checklist/check_notebook.py +++ b/tests/python/release_checklist/check_notebook.py @@ -23,8 +23,8 @@ def run(args: Namespace) -> None: args, f"{os.path.basename(__file__)}", recording_id=uuid4(), - default_blueprint=rrb.Grid(rrb.TextDocumentView(origin="readme")), ) + rr.send_blueprint(rrb.Grid(rrb.TextDocumentView(origin="readme")), make_active=True, make_default=True) log_readme() diff --git a/tests/python/release_checklist/check_out_of_tree_data_results.py b/tests/python/release_checklist/check_out_of_tree_data_results.py index 99f1edf440c7..e1d71272f26c 100644 --- a/tests/python/release_checklist/check_out_of_tree_data_results.py +++ b/tests/python/release_checklist/check_out_of_tree_data_results.py @@ -38,7 +38,8 @@ def log_data() -> None: def run(args: Namespace) -> None: - rr.script_setup(args, f"{os.path.basename(__file__)}", recording_id=uuid4(), default_blueprint=blueprint()) + rr.script_setup(args, f"{os.path.basename(__file__)}", recording_id=uuid4()) + rr.send_blueprint(blueprint(), make_active=True, make_default=True) log_readme() log_data() diff --git a/tests/python/release_checklist/check_overrides_2d.py b/tests/python/release_checklist/check_overrides_2d.py index d8dc0c24de94..64ef757769e4 100644 --- a/tests/python/release_checklist/check_overrides_2d.py +++ b/tests/python/release_checklist/check_overrides_2d.py @@ -67,6 +67,13 @@ def log_boxes() -> None: rr.Arrows2D(origins=[[-2.0, 0.0], [0.0, 0.0], [2.0, 0.0]], vectors=[[-2.0, 1.0], [0.0, 2.0], [2.0, 1.0]]), ) + +def run(args: Namespace) -> None: + rr.script_setup(args, f"{os.path.basename(__file__)}", recording_id=uuid4()) + + log_readme() + log_boxes() + visual_bounds = rrb.VisualBounds2D(x_range=[-5.5, 5.5], y_range=[-3.0, 3.0]) overrides = { "arrows": [ @@ -87,68 +94,58 @@ def log_boxes() -> None: rr.components.TextBatch(["TeenyYellow", "AverageCyan", "GigaPurple"]), ] - rr.send_blueprint( - rrb.Blueprint( - rrb.Grid( - rrb.TextDocumentView(origin="readme", name="Instructions"), - rrb.Vertical( - rrb.Spatial2DView( - name="1) Overrides, logged values & defaults", - visual_bounds=visual_bounds, - overrides=overrides, - defaults=defaults, - ), - rrb.Spatial2DView( - name="2) Logged values & defaults", - visual_bounds=visual_bounds, - defaults=defaults, - ), - rrb.Spatial2DView( - name="3) Logged values only", - visual_bounds=visual_bounds, - ), + blueprint = rrb.Blueprint( + rrb.Grid( + rrb.TextDocumentView(origin="readme", name="Instructions"), + rrb.Vertical( + rrb.Spatial2DView( + name="1) Overrides, logged values & defaults", + visual_bounds=visual_bounds, + overrides=overrides, + defaults=defaults, + ), + rrb.Spatial2DView( + name="2) Logged values & defaults", + visual_bounds=visual_bounds, + defaults=defaults, ), - rrb.Vertical( - rrb.Spatial2DView( - name="What you should get after removing overrides from 1)", - visual_bounds=visual_bounds, - defaults=defaults, - ), - rrb.Spatial2DView( - name="What you should get after removing defaults from 2)", - visual_bounds=visual_bounds, - ), - rrb.Spatial2DView( - name="What you should get after adding overrides & defaults to 3)", - visual_bounds=visual_bounds, - overrides={ - "arrows": [ - rrb.VisualizerOverrides([ - rrb.visualizers.Arrows2D, - rrb.visualizers.Points2D, - ]), - rr.components.Color([255, 255, 255]), - rr.components.Radius(0.1), - rr.components.Text("Cerberus"), - rr.components.Position2D([0.0, 0.0]), - ] - }, - ), + rrb.Spatial2DView( + name="3) Logged values only", + visual_bounds=visual_bounds, ), - grid_columns=3, - column_shares=[1, 1, 1], ), - rrb.BlueprintPanel(state="collapsed"), - rrb.TimePanel(state="collapsed"), - ) + rrb.Vertical( + rrb.Spatial2DView( + name="What you should get after removing overrides from 1)", + visual_bounds=visual_bounds, + defaults=defaults, + ), + rrb.Spatial2DView( + name="What you should get after removing defaults from 2)", + visual_bounds=visual_bounds, + ), + rrb.Spatial2DView( + name="What you should get after adding overrides & defaults to 3)", + visual_bounds=visual_bounds, + overrides={ + "arrows": [ + rrb.VisualizerOverrides([ + rrb.visualizers.Arrows2D, + rrb.visualizers.Points2D, + ]), + rr.components.Color([255, 255, 255]), + rr.components.Radius(0.1), + rr.components.Text("Cerberus"), + rr.components.Position2D([0.0, 0.0]), + ] + }, + ), + ), + grid_columns=3, + column_shares=[1, 1, 1], + ), ) - - -def run(args: Namespace) -> None: - rr.script_setup(args, f"{os.path.basename(__file__)}", recording_id=uuid4()) - - log_readme() - log_boxes() + rr.send_blueprint(blueprint, make_active=True, make_default=True) if __name__ == "__main__": diff --git a/tests/python/release_checklist/check_parallelism_caching_reentrancy.py b/tests/python/release_checklist/check_parallelism_caching_reentrancy.py index 304d66c1644d..842a1dd2e6da 100644 --- a/tests/python/release_checklist/check_parallelism_caching_reentrancy.py +++ b/tests/python/release_checklist/check_parallelism_caching_reentrancy.py @@ -177,7 +177,8 @@ def log_spatial() -> None: def run(args: Namespace) -> None: - rr.script_setup(args, f"{os.path.basename(__file__)}", recording_id=uuid4(), default_blueprint=blueprint()) + rr.script_setup(args, f"{os.path.basename(__file__)}", recording_id=uuid4()) + rr.send_blueprint(blueprint(), make_active=True, make_default=True) log_readme() log_text_logs() diff --git a/tests/python/release_checklist/check_plot_overrides.py b/tests/python/release_checklist/check_plot_overrides.py index cc3a482bb3ce..c46d88669f4f 100644 --- a/tests/python/release_checklist/check_plot_overrides.py +++ b/tests/python/release_checklist/check_plot_overrides.py @@ -62,6 +62,8 @@ def run(args: Namespace) -> None: log_readme() log_plots() + rr.send_blueprint(rr.blueprint.Blueprint(auto_layout=True, auto_views=True), make_active=True, make_default=True) + if __name__ == "__main__": import argparse diff --git a/tests/python/release_checklist/check_range_partial_updates.py b/tests/python/release_checklist/check_range_partial_updates.py index 39220eaf58d7..caeb50c805fc 100644 --- a/tests/python/release_checklist/check_range_partial_updates.py +++ b/tests/python/release_checklist/check_range_partial_updates.py @@ -98,10 +98,6 @@ def blueprint() -> rrb.BlueprintLike: ], grid_columns=3, ), - # NOTE: It looks nice but it's very annoying when going through several checklists. - # rrb.BlueprintPanel(state="collapsed"), - # rrb.TimePanel(state="collapsed"), - # rrb.SelectionPanel(state="collapsed"), ) @@ -134,7 +130,7 @@ def log_points() -> None: def run(args: Namespace) -> None: rr.script_setup(args, f"{os.path.basename(__file__)}", recording_id=uuid4()) - rr.send_blueprint(blueprint()) + rr.send_blueprint(blueprint(), make_active=True, make_default=True) log_readme() log_points() diff --git a/tests/python/release_checklist/check_rbl_import.py b/tests/python/release_checklist/check_rbl_import.py index 942fb8d3e33d..c74e93305f5d 100644 --- a/tests/python/release_checklist/check_rbl_import.py +++ b/tests/python/release_checklist/check_rbl_import.py @@ -37,9 +37,6 @@ def log_external_blueprint() -> None: rrb.TextDocumentView(origin="readme"), column_shares=[3, 2], ), - rrb.BlueprintPanel(state="collapsed"), - rrb.SelectionPanel(state="collapsed"), - rrb.TimePanel(state="collapsed"), ).save("some_unrelated_blueprint_app_id", tmp.name) rr.log_file_from_path(tmp.name) @@ -76,7 +73,9 @@ def run(args: Namespace) -> None: args, f"{os.path.basename(__file__)}", recording_id=uuid4(), - default_blueprint=rrb.Blueprint( + ) + rr.send_blueprint( + rrb.Blueprint( rrb.Horizontal( rrb.TimeSeriesView(origin="/"), rrb.TextDocumentView(origin="readme"), @@ -86,6 +85,8 @@ def run(args: Namespace) -> None: rrb.SelectionPanel(state="collapsed"), rrb.TimePanel(state="collapsed"), ), + make_active=True, + make_default=True, ) log_readme() diff --git a/tests/python/release_checklist/check_scalar_clears.py b/tests/python/release_checklist/check_scalar_clears.py index 81e922bf93c1..c3f025ccbaca 100644 --- a/tests/python/release_checklist/check_scalar_clears.py +++ b/tests/python/release_checklist/check_scalar_clears.py @@ -46,6 +46,8 @@ def run(args: Namespace) -> None: log_readme() log_plots() + rr.send_blueprint(rr.blueprint.Blueprint(auto_layout=True, auto_views=True), make_active=True, make_default=True) + if __name__ == "__main__": import argparse diff --git a/tests/python/release_checklist/check_static_components_ui.py b/tests/python/release_checklist/check_static_components_ui.py index 61bb20845ee1..6c53e9d66ca3 100644 --- a/tests/python/release_checklist/check_static_components_ui.py +++ b/tests/python/release_checklist/check_static_components_ui.py @@ -62,6 +62,8 @@ def run(args: Namespace) -> None: log_readme() log_some_views() + rr.send_blueprint(rr.blueprint.Blueprint(auto_layout=True, auto_views=True), make_active=True, make_default=True) + if __name__ == "__main__": import argparse diff --git a/tests/python/release_checklist/check_static_override.py b/tests/python/release_checklist/check_static_override.py index ddf28ccb33f3..7c2748c9733a 100644 --- a/tests/python/release_checklist/check_static_override.py +++ b/tests/python/release_checklist/check_static_override.py @@ -29,6 +29,8 @@ def run(args: Namespace) -> None: # Log it again, to ensure that the newest one is visible rr.log("points", rr.Points3D([[0, 0, 0], [1, 1, 1], [2, 2, 2]]), static=True) + rr.send_blueprint(rr.blueprint.Blueprint(auto_layout=True, auto_views=True), make_active=True, make_default=True) + if __name__ == "__main__": import argparse diff --git a/tests/python/release_checklist/check_transform3d_hierarchy.py b/tests/python/release_checklist/check_transform3d_hierarchy.py index 5e0d0f81bf8d..ea54715593ee 100644 --- a/tests/python/release_checklist/check_transform3d_hierarchy.py +++ b/tests/python/release_checklist/check_transform3d_hierarchy.py @@ -72,9 +72,9 @@ def log_data() -> None: rr.set_time_sequence("steps", 4) path += "scale_back_mat3x3/" # fmt: off - rr.log(path, rr.Transform3D(mat3x3=[1.0, 0.0, 0.0, - 0.0, 5.0, 0.0, - 0.0, 0.0, 1.0])) + rr.log(path, rr.Transform3D(mat3x3=[1.0, 0.0, 0.0, + 0.0, 5.0, 0.0, + 0.0, 0.0, 1.0])) # fmt: on rr.set_time_sequence("steps", 5) @@ -112,7 +112,8 @@ def log_data() -> None: def run(args: Namespace) -> None: - rr.script_setup(args, f"{os.path.basename(__file__)}", recording_id=uuid4(), default_blueprint=blueprint()) + rr.script_setup(args, f"{os.path.basename(__file__)}", recording_id=uuid4()) + rr.send_blueprint(blueprint(), make_active=True, make_default=True) # Extract the rerun_obj.zip file with zipfile.ZipFile(f"{rerun_obj_path}.zip", "r") as zip_ref: diff --git a/tests/python/release_checklist/check_version.py b/tests/python/release_checklist/check_version.py index 78d34a59a5d2..35ede9dc7f44 100644 --- a/tests/python/release_checklist/check_version.py +++ b/tests/python/release_checklist/check_version.py @@ -38,6 +38,8 @@ def run(args: Namespace) -> None: log_readme() log_the_versions() + rr.send_blueprint(rr.blueprint.Blueprint(auto_layout=True, auto_views=True), make_active=True, make_default=True) + if __name__ == "__main__": import argparse diff --git a/tests/python/release_checklist/check_video.py b/tests/python/release_checklist/check_video.py index 5dd2f4aec54d..14720f3cc626 100644 --- a/tests/python/release_checklist/check_video.py +++ b/tests/python/release_checklist/check_video.py @@ -66,20 +66,19 @@ def run(args: Namespace) -> None: static=True, # Static, so it shows up in the "video_time" timeline! ) - rr.send_blueprint( - rrb.Blueprint( - rrb.Grid( - rrb.TextDocumentView(origin="readme", name="Instructions"), - rrb.Spatial3DView(origin="/", name="AV1 frustum", contents="av1"), - rrb.Spatial2DView(origin="av1", name="AV1"), - rrb.Spatial2DView(origin="h264", name="H.264"), - rrb.Spatial2DView(origin="h265", name="H.265"), - rrb.Spatial2DView(origin="vp9", name="VP9"), - ), - rrb.TimePanel(state="collapsed"), - ) + blueprint = rrb.Blueprint( + rrb.Grid( + rrb.TextDocumentView(origin="readme", name="Instructions"), + rrb.Spatial3DView(origin="/", name="AV1 frustum", contents="av1"), + rrb.Spatial2DView(origin="av1", name="AV1"), + rrb.Spatial2DView(origin="h264", name="H.264"), + rrb.Spatial2DView(origin="h265", name="H.265"), + rrb.Spatial2DView(origin="vp9", name="VP9"), + ), ) + rr.send_blueprint(blueprint, make_active=True, make_default=True) + if __name__ == "__main__": import argparse From 091e57a6c0085e2ccfcc8477cc1b322f1ffef60f Mon Sep 17 00:00:00 2001 From: Zeljko Mihaljcic <7150613+zehiko@users.noreply.github.com> Date: Wed, 18 Dec 2024 07:57:54 +0100 Subject: [PATCH 15/30] Catalog view: fetch StoreInfo from the catalog and do the catalog data enrichment on the viewer side (#8504) ### What Rerun Data Platform now supports simple filtering by recording ids and also stores (some of the) fields required to create StoreInfo, hence we can fetch it from the catalog. Also, instead of doing all the arrow data manipulation to make DataframePart convertible to Rerun Chunk on the ReDap side, we now do it on the viewer side. --- crates/store/re_grpc_client/src/lib.rs | 177 ++++++++++++++++++++++--- 1 file changed, 160 insertions(+), 17 deletions(-) diff --git a/crates/store/re_grpc_client/src/lib.rs b/crates/store/re_grpc_client/src/lib.rs index 5b6f553ee428..f324862dc3a8 100644 --- a/crates/store/re_grpc_client/src/lib.rs +++ b/crates/store/re_grpc_client/src/lib.rs @@ -5,6 +5,7 @@ mod address; pub use address::{InvalidRedapAddress, RedapAddress}; use re_chunk::external::arrow2; use re_log_types::external::re_types_core::ComponentDescriptor; +use re_protos::remote_store::v0::CatalogFilter; use re_types::blueprint::archetypes::{ContainerBlueprint, ViewportBlueprint}; use re_types::blueprint::archetypes::{ViewBlueprint, ViewContents}; use re_types::blueprint::components::{ContainerKind, RootContainer}; @@ -16,6 +17,7 @@ use url::Url; // ---------------------------------------------------------------------------- use std::error::Error; +use std::sync::Arc; use arrow2::array::Utf8Array as Arrow2Utf8Array; use arrow2::datatypes::Field as Arrow2Field; @@ -175,6 +177,43 @@ async fn stream_recording_async( StorageNodeClient::new(tonic_client).max_decoding_message_size(usize::MAX) }; + re_log::debug!("Fetching catalog data for {recording_id}…"); + + let resp = client + .query_catalog(QueryCatalogRequest { + column_projection: None, // fetch all columns + filter: Some(CatalogFilter { + recording_ids: vec![RecordingId { + id: recording_id.clone(), + }], + }), + }) + .await + .map_err(TonicStatusError)? + .into_inner() + .filter_map(|resp| { + resp.and_then(|r| { + decode(r.encoder_version(), &r.payload) + .map_err(|err| tonic::Status::internal(err.to_string())) + }) + .transpose() + }) + .collect::, tonic::Status>>() + .await + .map_err(TonicStatusError)?; + + if resp.len() != 1 || resp[0].num_rows() != 1 { + return Err(StreamError::ChunkError(re_chunk::ChunkError::Malformed { + reason: format!( + "expected exactly one recording with id {recording_id}, got {}", + resp.len() + ), + })); + } + + let store_info = store_info_from_catalog_chunk(&resp[0], &recording_id)?; + let store_id = store_info.store_id.clone(); + re_log::debug!("Fetching {recording_id}…"); let mut resp = client @@ -196,19 +235,6 @@ async fn stream_recording_async( drop(client); - // TODO(zehiko) - we need a separate gRPC endpoint for fetching Store info REDAP #85 - let store_id = StoreId::from_string(StoreKind::Recording, recording_id.clone()); - - let store_info = StoreInfo { - application_id: ApplicationId::from("redap_recording"), - store_id: store_id.clone(), - cloned_from: None, - is_official_example: false, - started: Time::now(), - store_source: StoreSource::Unknown, - store_version: None, - }; - // We need a whole StoreInfo here. if tx .send(LogMsg::SetStoreInfo(SetStoreInfo { @@ -242,6 +268,51 @@ async fn stream_recording_async( Ok(()) } +fn store_info_from_catalog_chunk( + tc: &TransportChunk, + recording_id: &str, +) -> Result { + let store_id = StoreId::from_string(StoreKind::Recording, recording_id.to_owned()); + + let (_field, data) = tc + .components() + .find(|(f, _)| f.name == "application_id") + .ok_or(StreamError::ChunkError(re_chunk::ChunkError::Malformed { + reason: "no application_id field found".to_owned(), + }))?; + let app_id = data + .as_any() + .downcast_ref::>() + .ok_or(StreamError::ChunkError(re_chunk::ChunkError::Malformed { + reason: format!("application_id must be a utf8 array: {:?}", tc.schema), + }))? + .value(0); + + let (_field, data) = tc + .components() + .find(|(f, _)| f.name == "start_time") + .ok_or(StreamError::ChunkError(re_chunk::ChunkError::Malformed { + reason: "no start_time field found".to_owned(), + }))?; + let start_time = data + .as_any() + .downcast_ref::() + .ok_or(StreamError::ChunkError(re_chunk::ChunkError::Malformed { + reason: format!("start_time must be an int64 array: {:?}", tc.schema), + }))? + .value(0); + + Ok(StoreInfo { + application_id: ApplicationId::from(app_id), + store_id: store_id.clone(), + cloned_from: None, + is_official_example: false, + started: Time::from_ns_since_epoch(start_time), + store_source: StoreSource::Unknown, + store_version: None, + }) +} + async fn stream_catalog_async( tx: re_smart_channel::Sender, redap_endpoint: Url, @@ -318,16 +389,88 @@ async fn stream_catalog_async( re_log::info!("Starting to read..."); while let Some(result) = resp.next().await { - let mut tc = result.map_err(TonicStatusError)?; - // received TransportChunk doesn't have ChunkId, hence we need to add it before converting - // to Chunk + let input = result.map_err(TonicStatusError)?; + + // Catalog received from the ReDap server isn't suitable for direct conversion to a Rerun Chunk: + // - conversion expects "data" columns to be ListArrays, hence we need to convert any individual row column data to ListArray + // - conversion expects the input TransportChunk to have a ChunkId so we need to add that piece of metadata + + let mut fields = Vec::new(); + let mut arrays = Vec::new(); + // add the (row id) control field + let (row_id_field, row_id_data) = input.controls().next().ok_or( + StreamError::ChunkError(re_chunk::ChunkError::Malformed { + reason: "no control field found".to_owned(), + }), + )?; + + fields.push( + Arrow2Field::new( + RowId::name().to_string(), // need to rename to Rerun Chunk expected control field + row_id_field.data_type().clone(), + false, /* not nullable */ + ) + .with_metadata(TransportChunk::field_metadata_control_column()), + ); + arrays.push(row_id_data.clone()); + + // next add any timeline field + for (field, data) in input.timelines() { + fields.push(field.clone()); + arrays.push(data.clone()); + } + + // now add all the 'data' fields - we slice each column array into individual arrays and then convert the whole lot into a ListArray + for (field, data) in input.components() { + let data_field_inner = + Arrow2Field::new("item", field.data_type().clone(), true /* nullable */); + + let data_field = Arrow2Field::new( + field.name.clone(), + arrow2::datatypes::DataType::List(Arc::new(data_field_inner.clone())), + false, /* not nullable */ + ) + .with_metadata(TransportChunk::field_metadata_data_column()); + + let mut sliced: Vec> = Vec::new(); + for idx in 0..data.len() { + let mut array = data.clone(); + array.slice(idx, 1); + sliced.push(array); + } + + let data_arrays = sliced.iter().map(|e| Some(e.as_ref())).collect::>(); + #[allow(clippy::unwrap_used)] // we know we've given the right field type + let data_field_array: arrow2::array::ListArray = + re_chunk::util::arrays_to_list_array( + data_field_inner.data_type().clone(), + &data_arrays, + ) + .unwrap(); + + fields.push(data_field); + arrays.push(Box::new(data_field_array)); + } + + let mut schema = arrow2::datatypes::Schema::from(fields); + schema.metadata.insert( + TransportChunk::CHUNK_METADATA_KEY_ENTITY_PATH.to_owned(), + "catalog".to_owned(), + ); + + // modified and enriched TransportChunk + let mut tc = TransportChunk { + schema, + data: arrow2::chunk::Chunk::new(arrays), + }; + tc.schema.metadata.insert( TransportChunk::CHUNK_METADATA_KEY_ID.to_owned(), ChunkId::new().to_string(), ); let mut chunk = Chunk::from_transport(&tc)?; - // enrich catalog data with RecordingUri that's based on the ReDap endpoint (that we know) + // finally, enrich catalog data with RecordingUri that's based on the ReDap endpoint (that we know) // and the recording id (that we have in the catalog data) let host = redap_endpoint .host() From 84da13220f7bbd880a579a37853ebb1ea8b81a2c Mon Sep 17 00:00:00 2001 From: Jeremy Leibs Date: Wed, 18 Dec 2024 08:20:46 +0100 Subject: [PATCH 16/30] Update the remote APIs to take and send a Table (#8521) This allows the update APIs to now support multi-recording updates, and generally gives users more direct control over things like the column metadata, etc. --- .../proto/rerun/v0/remote_store.proto | 1 - .../re_protos/src/v0/rerun.remote_store.v0.rs | 2 - examples/python/remote/metadata.py | 17 +- rerun_py/rerun_bindings/rerun_bindings.pyi | 22 +-- rerun_py/rerun_bindings/types.py | 5 +- rerun_py/src/remote.rs | 158 ++++++------------ 6 files changed, 83 insertions(+), 122 deletions(-) diff --git a/crates/store/re_protos/proto/rerun/v0/remote_store.proto b/crates/store/re_protos/proto/rerun/v0/remote_store.proto index 2955f45b8b3c..5d2f68ca3794 100644 --- a/crates/store/re_protos/proto/rerun/v0/remote_store.proto +++ b/crates/store/re_protos/proto/rerun/v0/remote_store.proto @@ -44,7 +44,6 @@ message RegisterRecordingRequest { // ---------------- UpdateCatalog ----------------- message UpdateCatalogRequest { - rerun.common.v0.RecordingId recording_id = 1; DataframePart metadata = 2; } diff --git a/crates/store/re_protos/src/v0/rerun.remote_store.v0.rs b/crates/store/re_protos/src/v0/rerun.remote_store.v0.rs index 1429146e776d..a755b57daac4 100644 --- a/crates/store/re_protos/src/v0/rerun.remote_store.v0.rs +++ b/crates/store/re_protos/src/v0/rerun.remote_store.v0.rs @@ -47,8 +47,6 @@ impl ::prost::Name for RegisterRecordingRequest { } #[derive(Clone, PartialEq, ::prost::Message)] pub struct UpdateCatalogRequest { - #[prost(message, optional, tag = "1")] - pub recording_id: ::core::option::Option, #[prost(message, optional, tag = "2")] pub metadata: ::core::option::Option, } diff --git a/examples/python/remote/metadata.py b/examples/python/remote/metadata.py index e199499d8f2a..31371bfac2d3 100644 --- a/examples/python/remote/metadata.py +++ b/examples/python/remote/metadata.py @@ -14,23 +14,31 @@ subparsers = parser.add_subparsers(dest="subcommand") print_cmd = subparsers.add_parser("print", help="Print everything") + register_cmd = subparsers.add_parser("register", help="Register a new recording") update_cmd = subparsers.add_parser("update", help="Update metadata for a recording") update_cmd.add_argument("id", help="ID of the recording to update") update_cmd.add_argument("key", help="Key of the metadata to update") update_cmd.add_argument("value", help="Value of the metadata to update") + register_cmd.add_argument("storage_url", help="Storage URL to register") + args = parser.parse_args() # Register the new rrd conn = rr.remote.connect("http://0.0.0.0:51234") - catalog = pl.from_arrow(conn.query_catalog()) + catalog = pl.from_arrow(conn.query_catalog().read_all()) if args.subcommand == "print": print(catalog) - if args.subcommand == "update": + elif args.subcommand == "register": + extra_metadata = pa.Table.from_pydict({"extra": [42]}) + id = conn.register(args.storage_url, extra_metadata) + print(f"Registered new recording with ID: {id}") + + elif args.subcommand == "update": id = catalog.filter(catalog["id"].str.starts_with(args.id)).select(pl.first("id")).item() if id is None: @@ -38,4 +46,7 @@ exit(1) print(f"Updating metadata for {id}") - conn.update_catalog(id, {args.key: pa.array([args.value])}) + new_metadata = pa.Table.from_pydict({"id": [id], args.key: [args.value]}) + print(new_metadata) + + conn.update_catalog(new_metadata) diff --git a/rerun_py/rerun_bindings/rerun_bindings.pyi b/rerun_py/rerun_bindings/rerun_bindings.pyi index 53fd6781b43f..bd046bf15069 100644 --- a/rerun_py/rerun_bindings/rerun_bindings.pyi +++ b/rerun_py/rerun_bindings/rerun_bindings.pyi @@ -3,7 +3,7 @@ from typing import Iterator, Optional, Sequence, Union import pyarrow as pa -from .types import AnyColumn, AnyComponentColumn, ComponentLike, IndexValuesLike, MetadataLike, ViewContentsLike +from .types import AnyColumn, AnyComponentColumn, ComponentLike, IndexValuesLike, TableLike, ViewContentsLike class IndexColumnDescriptor: """ @@ -581,7 +581,7 @@ class StorageNodeClient: """Get the metadata for all recordings in the storage node.""" ... - def register(self, storage_url: str, metadata: Optional[dict[str, MetadataLike]] = None) -> str: + def register(self, storage_url: str, metadata: Optional[TableLike] = None) -> str: """ Register a recording along with some metadata. @@ -589,22 +589,24 @@ class StorageNodeClient: ---------- storage_url : str The URL to the storage location. - metadata : dict[str, MetadataLike] - A dictionary where the keys are the metadata columns and the values are pyarrow arrays. + metadata : Optional[Table | RecordBatch] + A pyarrow Table or RecordBatch containing the metadata to update. + This Table must contain only a single row. """ ... - def update_catalog(self, id: str, metadata: dict[str, MetadataLike]) -> None: + def update_catalog(self, metadata: TableLike) -> None: """ - Update the metadata for the recording with the given id. + Update the catalog metadata for one or more recordings. + + The updates are provided as a pyarrow Table or RecordBatch containing the metadata to update. + The Table must contain an 'id' column, which is used to specify the recording to update for each row. Parameters ---------- - id : str - The id of the recording to update. - metadata : dict[str, MetadataLike] - A dictionary where the keys are the metadata columns and the values are pyarrow arrays. + metadata : Table | RecordBatch + A pyarrow Table or RecordBatch containing the metadata to update. """ ... diff --git a/rerun_py/rerun_bindings/types.py b/rerun_py/rerun_bindings/types.py index c5ddf94e7477..a38e70036d34 100644 --- a/rerun_py/rerun_bindings/types.py +++ b/rerun_py/rerun_bindings/types.py @@ -68,4 +68,7 @@ This can be any numpy-compatible array of integers, or a [`pa.Int64Array`][] """ -MetadataLike: TypeAlias = pa.Array +TableLike: TypeAlias = Union[pa.Table, pa.RecordBatch, pa.RecordBatchReader] +""" +A type alias for TableLike pyarrow objects. +""" diff --git a/rerun_py/src/remote.rs b/rerun_py/src/remote.rs index a74f3a1a0666..2619d3990088 100644 --- a/rerun_py/src/remote.rs +++ b/rerun_py/src/remote.rs @@ -1,11 +1,12 @@ #![allow(unsafe_op_in_unsafe_fn)] use arrow::{ - array::{ArrayData, RecordBatch, RecordBatchIterator, RecordBatchReader}, + array::{RecordBatch, RecordBatchIterator, RecordBatchReader}, datatypes::Schema, + ffi_stream::ArrowArrayStreamReader, pyarrow::PyArrowType, }; // False positive due to #[pyfunction] macro -use pyo3::{exceptions::PyRuntimeError, prelude::*, types::PyDict, Bound, PyResult}; +use pyo3::{exceptions::PyRuntimeError, prelude::*, Bound, PyResult}; use re_chunk::{Chunk, TransportChunk}; use re_chunk_store::ChunkStore; use re_dataframe::ChunkStoreHandle; @@ -134,17 +135,14 @@ impl PyStorageNodeClient { /// ---------- /// storage_url : str /// The URL to the storage location. - /// metadata : dict[str, MetadataLike] - /// A dictionary where the keys are the metadata columns and the values are pyarrow arrays. + /// metadata : Optional[Table | RecordBatch] + /// A pyarrow Table or RecordBatch containing the metadata to update. + /// This Table must contain only a single row. #[pyo3(signature = ( storage_url, metadata = None ))] - fn register( - &mut self, - storage_url: &str, - metadata: Option<&Bound<'_, PyDict>>, - ) -> PyResult { + fn register(&mut self, storage_url: &str, metadata: Option) -> PyResult { self.runtime.block_on(async { let storage_url = url::Url::parse(storage_url) .map_err(|err| PyRuntimeError::new_err(err.to_string()))?; @@ -152,51 +150,32 @@ impl PyStorageNodeClient { let _obj = object_store::ObjectStoreScheme::parse(&storage_url) .map_err(|err| PyRuntimeError::new_err(err.to_string()))?; - let payload = metadata + let metadata = metadata .map(|metadata| { - let (schema, data): ( - Vec, - Vec>, - ) = metadata - .iter() - .map(|(key, value)| { - let key = key.to_string(); - let value = value.extract::()?; - let value_array = value.to_arrow2()?; - let field = arrow2::datatypes::Field::new( - key, - value_array.data_type().clone(), - true, - ); - Ok((field, value_array)) - }) - .collect::>>()? - .into_iter() - .unzip(); - - let schema = arrow2::datatypes::Schema::from(schema); - let data = arrow2::chunk::Chunk::new(data); - - let metadata_tc = TransportChunk { - schema: schema.clone(), - data, - }; + let metadata = metadata.into_record_batch()?; + + if metadata.num_rows() != 1 { + return Err(PyRuntimeError::new_err( + "Metadata must contain exactly one row", + )); + } + + let metadata_tc = TransportChunk::from_arrow_record_batch(&metadata); encode(EncoderVersion::V0, metadata_tc) .map_err(|err| PyRuntimeError::new_err(err.to_string())) }) .transpose()? - // TODO(zehiko) this is going away soon - .ok_or(PyRuntimeError::new_err("No metadata"))?; + .map(|payload| DataframePart { + encoder_version: EncoderVersion::V0 as i32, + payload, + }); let request = RegisterRecordingRequest { // TODO(jleibs): Description should really just be in the metadata description: Default::default(), storage_url: storage_url.to_string(), - metadata: Some(DataframePart { - encoder_version: EncoderVersion::V0 as i32, - payload, - }), + metadata, typ: RecordingType::Rrd.into(), }; @@ -226,48 +205,33 @@ impl PyStorageNodeClient { }) } - /// Update the metadata for the recording with the given id. + /// Update the catalog metadata for one or more recordings. + /// + /// The updates are provided as a pyarrow Table or RecordBatch containing the metadata to update. + /// The Table must contain an 'id' column, which is used to specify the recording to update for each row. /// /// Parameters /// ---------- - /// id : str - /// The id of the recording to update. - /// metadata : dict[str, MetadataLike] - /// A dictionary where the keys are the metadata columns and the values are pyarrow arrays. + /// metadata : Table | RecordBatch + /// A pyarrow Table or RecordBatch containing the metadata to update. #[pyo3(signature = ( - id, metadata ))] - fn update_catalog(&mut self, id: &str, metadata: &Bound<'_, PyDict>) -> PyResult<()> { + #[allow(clippy::needless_pass_by_value)] + fn update_catalog(&mut self, metadata: MetadataLike) -> PyResult<()> { self.runtime.block_on(async { - let (schema, data): ( - Vec, - Vec>, - ) = metadata - .iter() - .map(|(key, value)| { - let key = key.to_string(); - let value = value.extract::()?; - let value_array = value.to_arrow2()?; - let field = - arrow2::datatypes::Field::new(key, value_array.data_type().clone(), true); - Ok((field, value_array)) - }) - .collect::>>()? - .into_iter() - .unzip(); + let metadata = metadata.into_record_batch()?; - let schema = arrow2::datatypes::Schema::from(schema); - - let data = arrow2::chunk::Chunk::new(data); + // TODO(jleibs): This id name should probably come from `re_protos` + if metadata.schema().column_with_name("id").is_none() { + return Err(PyRuntimeError::new_err( + "Metadata must contain an 'id' column", + )); + } - let metadata_tc = TransportChunk { - schema: schema.clone(), - data, - }; + let metadata_tc = TransportChunk::from_arrow_record_batch(&metadata); let request = UpdateCatalogRequest { - recording_id: Some(RecordingId { id: id.to_owned() }), metadata: Some(DataframePart { encoder_version: EncoderVersion::V0 as i32, payload: encode(EncoderVersion::V0, metadata_tc) @@ -363,39 +327,23 @@ impl PyStorageNodeClient { /// A type alias for metadata. #[derive(FromPyObject)] enum MetadataLike { - PyArrow(PyArrowType), - // TODO(jleibs): Support converting other primitives + RecordBatch(PyArrowType), + Reader(PyArrowType), } impl MetadataLike { - fn to_arrow2(&self) -> PyResult> { - match self { - Self::PyArrow(array) => { - let array = arrow2::array::from_data(&array.0); - if array.len() == 1 { - Ok(array) - } else { - Err(PyRuntimeError::new_err( - "Metadata must be a single array, not a list", - )) - } - } - } - } - - #[allow(dead_code)] - fn to_arrow(&self) -> PyResult> { - match self { - Self::PyArrow(array) => { - let array = arrow::array::make_array(array.0.clone()); - if array.len() == 1 { - Ok(array) - } else { - Err(PyRuntimeError::new_err( - "Metadata must be a single array, not a list", - )) - } - } - } + fn into_record_batch(self) -> PyResult { + let (schema, batches) = match self { + Self::RecordBatch(record_batch) => (record_batch.0.schema(), vec![record_batch.0]), + Self::Reader(reader) => ( + reader.0.schema(), + reader.0.collect::, _>>().map_err(|err| { + PyRuntimeError::new_err(format!("Failed to read RecordBatches: {err}")) + })?, + ), + }; + + arrow::compute::concat_batches(&schema, &batches) + .map_err(|err| PyRuntimeError::new_err(err.to_string())) } } From e9b2bff3801b8b8bf2f01270d7f847fdf803506c Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Wed, 18 Dec 2024 08:42:38 +0100 Subject: [PATCH 17/30] Hide graph edges from individual graph node ui (#8511) ### Related * https://github.com/rerun-io/rerun/issues/7026 ### What Lots of considerations & (soft) implications in this hack, see comment. The important outcome here is that node hover now looks like this: ![image](https://github.com/user-attachments/assets/5f4e693b-19cf-4ac5-b359-1354dd8377e9) node selection: ![image](https://github.com/user-attachments/assets/be75a273-bcb6-4bd4-b90a-5a19c994eb0f) and node entity selection (note that edges are still around: ![image](https://github.com/user-attachments/assets/e76c7cf9-3a1b-4687-bc61-10c6ace02103) also you can still browse the edges: ![image](https://github.com/user-attachments/assets/90c5d116-e9fe-4e4f-8032-ce8687e80097) --- crates/viewer/re_data_ui/src/instance_path.rs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/crates/viewer/re_data_ui/src/instance_path.rs b/crates/viewer/re_data_ui/src/instance_path.rs index c2bdecf82db7..7030face69d7 100644 --- a/crates/viewer/re_data_ui/src/instance_path.rs +++ b/crates/viewer/re_data_ui/src/instance_path.rs @@ -67,7 +67,7 @@ impl DataUi for InstancePath { .filter(|c| c.is_indicator_component()) .count(); - let components = latest_at(db, query, entity_path, &components); + let mut components = latest_at(db, query, entity_path, &components); if components.is_empty() { ui_layout.label( @@ -96,6 +96,20 @@ impl DataUi for InstancePath { ), ); } else { + // TODO(#7026): Instances today are too poorly defined: + // For many archetypes it makes sense to slice through all their component arrays with the same index. + // However, there are cases when there are multiple dimensions of slicing that make sense. + // This is most obvious for meshes & graph nodes where there are different dimensions for vertices/edges/etc. + // + // For graph nodes this is particularly glaring since our indicices imply nodes today and + // unlike with meshes it's very easy to hover & select individual nodes. + // In order to work around the GraphEdges showing up associated with random nodes, we just hide them here. + // (this is obviously a hack and these relationships should be formalized such that they are accessible to the UI, see ticket link above) + if !self.is_all() { + components + .retain(|(component, _chunk)| component != &components::GraphEdge::name()); + } + component_list_ui( ctx, ui, From ed05c75a0ce9d06c1dd786aefc94c22a8630ac7a Mon Sep 17 00:00:00 2001 From: Antoine Beyeler <49431240+abey79@users.noreply.github.com> Date: Wed, 18 Dec 2024 09:02:02 +0100 Subject: [PATCH 18/30] Fix multi-entity drag-and-drop only adding one entity (#8519) ### Related * Related to #8518 * Related to #8431 ### What Fix a bug in #8431 where multi-entity drag-and-drop would only add a single entity due to a foot-gun in our entity path filter mutation API (see #8518 for more). Also add a new checklist. --- crates/top/rerun/src/commands/entrypoint.rs | 6 +- crates/viewer/re_viewport/src/viewport_ui.rs | 22 ++++--- .../src/view_contents.rs | 34 ++++++++++- .../check_multi_entity_drag_and_drop.py | 60 +++++++++++++++++++ 4 files changed, 107 insertions(+), 15 deletions(-) create mode 100644 tests/python/release_checklist/check_multi_entity_drag_and_drop.py diff --git a/crates/top/rerun/src/commands/entrypoint.rs b/crates/top/rerun/src/commands/entrypoint.rs index 5ef16f301e40..6ea1089cb469 100644 --- a/crates/top/rerun/src/commands/entrypoint.rs +++ b/crates/top/rerun/src/commands/entrypoint.rs @@ -621,7 +621,7 @@ where } fn run_impl( - main_thread_token: crate::MainThreadToken, + _main_thread_token: crate::MainThreadToken, _build_info: re_build_info::BuildInfo, call_source: CallSource, args: Args, @@ -838,10 +838,10 @@ fn run_impl( } else { #[cfg(feature = "native_viewer")] return re_viewer::run_native_app( - main_thread_token, + _main_thread_token, Box::new(move |cc| { let mut app = re_viewer::App::new( - main_thread_token, + _main_thread_token, _build_info, &call_source.app_env(), startup_options, diff --git a/crates/viewer/re_viewport/src/viewport_ui.rs b/crates/viewer/re_viewport/src/viewport_ui.rs index 602c57a7f67b..ceba4abe229e 100644 --- a/crates/viewer/re_viewport/src/viewport_ui.rs +++ b/crates/viewer/re_viewport/src/viewport_ui.rs @@ -6,7 +6,7 @@ use ahash::HashMap; use egui_tiles::{Behavior as _, EditAction}; use re_context_menu::{context_menu_ui_for_item, SelectionUpdateBehavior}; -use re_log_types::{EntityPath, EntityPathRule}; +use re_log_types::{EntityPath, EntityPathRule, RuleEffect}; use re_ui::{design_tokens, ContextExt as _, DesignTokens, Icon, UiExt as _}; use re_viewer_context::{ blueprint_id_to_tile_id, icon_for_container_kind, Contents, DragAndDropFeedback, @@ -277,14 +277,18 @@ impl ViewportUi { if ctx.egui_ctx.input(|i| i.pointer.any_released()) { egui::DragAndDrop::clear_payload(ctx.egui_ctx); - for entity in entities { - if can_entity_be_added(entity) { - view_blueprint.contents.raw_add_entity_inclusion( - ctx, - EntityPathRule::including_subtree(entity.clone()), - ); - } - } + view_blueprint + .contents + .mutate_entity_path_filter(ctx, |filter| { + for entity in entities { + if can_entity_be_added(entity) { + filter.add_rule( + RuleEffect::Include, + EntityPathRule::including_subtree(entity.clone()), + ); + } + } + }); ctx.selection_state() .set_selection(Item::View(view_blueprint.id)); diff --git a/crates/viewer/re_viewport_blueprint/src/view_contents.rs b/crates/viewer/re_viewport_blueprint/src/view_contents.rs index ef4079f1f515..7988a7c9d65a 100644 --- a/crates/viewer/re_viewport_blueprint/src/view_contents.rs +++ b/crates/viewer/re_viewport_blueprint/src/view_contents.rs @@ -142,6 +142,9 @@ impl ViewContents { ); } + /// Set the entity path filter. WARNING: a single mutation is allowed per frame, or data will be + /// lost. + //TODO(#8518): address this massive foot-gun. pub fn set_entity_path_filter( &self, ctx: &ViewerContext<'_>, @@ -184,40 +187,65 @@ impl ViewContents { } } - /// Remove a subtree and any existing rules that it would match. + /// Perform arbitrary mutation on the entity path filter. WARNING: a single mutation is allowed + /// per frame, or data will be lost. + /// + /// This method exists because of the single mutation per frame limitation. It currently is the + /// only way to perform multiple mutations on the entity path filter in a single frame. + //TODO(#8518): address this massive foot-gun. + pub fn mutate_entity_path_filter( + &self, + ctx: &ViewerContext<'_>, + f: impl FnOnce(&mut EntityPathFilter), + ) { + let mut new_entity_path_filter = self.entity_path_filter.clone(); + f(&mut new_entity_path_filter); + self.set_entity_path_filter(ctx, &new_entity_path_filter); + } + + /// Remove a subtree and any existing rules that it would match. WARNING: a single mutation is + /// allowed per frame, or data will be lost. /// /// Because most-specific matches win, if we only add a subtree exclusion /// it can still be overridden by existing inclusions. This method ensures /// that not only do we add a subtree exclusion, but clear out any existing /// inclusions or (now redundant) exclusions that would match the subtree. + //TODO(#8518): address this massive foot-gun. pub fn remove_subtree_and_matching_rules(&self, ctx: &ViewerContext<'_>, path: EntityPath) { let mut new_entity_path_filter = self.entity_path_filter.clone(); new_entity_path_filter.remove_subtree_and_matching_rules(path); self.set_entity_path_filter(ctx, &new_entity_path_filter); } - /// Directly add an exclusion rule to the [`EntityPathFilter`]. + /// Directly add an exclusion rule to the [`EntityPathFilter`]. WARNING: a single mutation is + /// allowed per frame, or data will be lost. /// /// This is a direct modification of the filter and will not do any simplification /// related to overlapping or conflicting rules. /// /// If you are trying to remove an entire subtree, prefer using [`Self::remove_subtree_and_matching_rules`]. + //TODO(#8518): address this massive foot-gun. pub fn raw_add_entity_exclusion(&self, ctx: &ViewerContext<'_>, rule: EntityPathRule) { let mut new_entity_path_filter = self.entity_path_filter.clone(); new_entity_path_filter.add_rule(RuleEffect::Exclude, rule); self.set_entity_path_filter(ctx, &new_entity_path_filter); } - /// Directly add an inclusion rule to the [`EntityPathFilter`]. + /// Directly add an inclusion rule to the [`EntityPathFilter`]. WARNING: a single mutation is + /// allowed per frame, or data will be lost. /// /// This is a direct modification of the filter and will not do any simplification /// related to overlapping or conflicting rules. + //TODO(#8518): address this massive foot-gun. pub fn raw_add_entity_inclusion(&self, ctx: &ViewerContext<'_>, rule: EntityPathRule) { let mut new_entity_path_filter = self.entity_path_filter.clone(); new_entity_path_filter.add_rule(RuleEffect::Include, rule); self.set_entity_path_filter(ctx, &new_entity_path_filter); } + /// Remove rules for a given entity. WARNING: a single mutation is allowed per frame, or data + /// will be lost. + //TODO(#8518): address this massive foot-gun. pub fn remove_filter_rule_for(&self, ctx: &ViewerContext<'_>, ent_path: &EntityPath) { let mut new_entity_path_filter = self.entity_path_filter.clone(); new_entity_path_filter.remove_rule_for(ent_path); diff --git a/tests/python/release_checklist/check_multi_entity_drag_and_drop.py b/tests/python/release_checklist/check_multi_entity_drag_and_drop.py new file mode 100644 index 000000000000..e541458b3881 --- /dev/null +++ b/tests/python/release_checklist/check_multi_entity_drag_and_drop.py @@ -0,0 +1,60 @@ +from __future__ import annotations + +import os +from argparse import Namespace +from uuid import uuid4 + +import numpy as np +import rerun as rr +import rerun.blueprint as rrb + +README = """\ +# Multi-entity drag-and-drop + +This test checks that dragging multiple entities to a view correctly adds all entities. + +1. Multi-select `cos_curve` and `line_curve` entities in the streams tree. +2. Drag them to the PLOT view. +3. _Expect_: both entities are visible in the plot view and each are listed in the view's entity path filter. +""" + + +def log_readme() -> None: + rr.log("readme", rr.TextDocument(README, media_type=rr.MediaType.MARKDOWN), static=True) + + +def blueprint() -> rrb.BlueprintLike: + return rrb.Vertical( + rrb.TextDocumentView(origin="readme"), + rrb.TimeSeriesView(origin="/", contents=[], name="PLOT"), + ) + + +def log_some_scalar_entities() -> None: + times = np.arange(100) + curves = [ + ("cos_curve", np.cos(times / 100 * 2 * np.pi)), + ("line_curve", times / 100 + 0.2), + ] + + time_column = rr.TimeSequenceColumn("frame", times) + + for path, curve in curves: + rr.send_columns(path, times=[time_column], components=[rr.components.ScalarBatch(curve)]) + + +def run(args: Namespace) -> None: + rr.script_setup(args, f"{os.path.basename(__file__)}", recording_id=uuid4()) + rr.send_blueprint(blueprint(), make_default=True, make_active=True) + + log_readme() + log_some_scalar_entities() + + +if __name__ == "__main__": + import argparse + + parser = argparse.ArgumentParser(description="Interactive release checklist") + rr.script_add_args(parser) + args = parser.parse_args() + run(args) From c5ee5d35d178950aece1d7f65a42a42367e2f9f0 Mon Sep 17 00:00:00 2001 From: Antoine Beyeler <49431240+abey79@users.noreply.github.com> Date: Wed, 18 Dec 2024 09:23:31 +0100 Subject: [PATCH 19/30] Fix cargo warning (#8523) The warning: ``` warning: /Users/hhip/src/rerun/crates/utils/re_capabilities/Cargo.toml: `default-features` is ignored for egui, since `default-features` was not specified for `workspace.dependencies.egui`, this could become a hard error in the future ``` --- crates/utils/re_capabilities/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/utils/re_capabilities/Cargo.toml b/crates/utils/re_capabilities/Cargo.toml index d4c36f8b600e..7b9a410df627 100644 --- a/crates/utils/re_capabilities/Cargo.toml +++ b/crates/utils/re_capabilities/Cargo.toml @@ -31,5 +31,5 @@ egui = ["dep:egui"] # External dependencies: document-features.workspace = true -egui = { workspace = true, default-features = false, optional = true } +egui = { workspace = true, optional = true } static_assertions.workspace = true From 9d38189191ca028a2beffb1c247dfd3a2a64d6d8 Mon Sep 17 00:00:00 2001 From: Antoine Beyeler <49431240+abey79@users.noreply.github.com> Date: Wed, 18 Dec 2024 11:40:35 +0100 Subject: [PATCH 20/30] Fix undo not working in some entity drag-and-drop instances (#8526) This is a band-aid patch to address an issue with entity path filter which would result in the following behaviours: - the entity path filter would be perma-writen to the blueprint store when the view is selected (in some cases) - in such cases, this would break undo on user change (aka with entity drag-and-drop) The core issue is deeper and might cause panics with rust 1.81+. The TL;DR is that the current `EntityPathFilter` type is ambiguous as to whether its content has substitutions (aka $origin) applied or not. In particular `Eq` and `Ord` apply to unsubstituted, resp. substituted content (which can lead to the above panic). This should be further cleaned by having two structures, one unsubstituted and another substituted. --------- Co-authored-by: Clement Rey --- crates/store/re_log_types/src/path/entity_path_filter.rs | 5 ++++- crates/viewer/re_selection_panel/src/selection_panel.rs | 9 +++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/crates/store/re_log_types/src/path/entity_path_filter.rs b/crates/store/re_log_types/src/path/entity_path_filter.rs index a59629c1e089..9f94525e9bcc 100644 --- a/crates/store/re_log_types/src/path/entity_path_filter.rs +++ b/crates/store/re_log_types/src/path/entity_path_filter.rs @@ -16,8 +16,11 @@ pub enum EntityPathFilterParseError { } /// A set of substitutions for entity paths. +/// +/// Important: the same substitutions must be used in every place we parse entity path filters. +// TODO(ab): the above requirement is a foot-gun we already fell in and should be addressed. #[derive(Default)] -pub struct EntityPathSubs(pub HashMap); +pub struct EntityPathSubs(HashMap); impl EntityPathSubs { /// Create a new set of substitutions from a single origin. diff --git a/crates/viewer/re_selection_panel/src/selection_panel.rs b/crates/viewer/re_selection_panel/src/selection_panel.rs index 9d2cf9e3209c..4bec1216ff8d 100644 --- a/crates/viewer/re_selection_panel/src/selection_panel.rs +++ b/crates/viewer/re_selection_panel/src/selection_panel.rs @@ -7,7 +7,7 @@ use re_data_ui::{ DataUi, }; use re_entity_db::{EntityPath, InstancePath}; -use re_log_types::{ComponentPath, EntityPathFilter}; +use re_log_types::{ComponentPath, EntityPathFilter, EntityPathSubs}; use re_types::blueprint::components::Interactive; use re_ui::{ icons, @@ -559,7 +559,12 @@ fn entity_path_filter_ui( } // Apply the edit. - let new_filter = EntityPathFilter::parse_forgiving(&filter_string, &Default::default()); + // + // NOTE: The comparison of `EntityPathFilter` is done on the _expanded_ data (i.e. with variables substituted), + // so we must make sure to expand the new filter too before we compare it to the existing one. + // See + let new_filter = + EntityPathFilter::parse_forgiving(&filter_string, &EntityPathSubs::new_with_origin(origin)); if &new_filter == filter { None // no change } else { From fd1adf94980dd2fff0ae1a6904f60db89c1a539f Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Wed, 18 Dec 2024 13:29:03 +0100 Subject: [PATCH 21/30] Use single log call in graph examples (#8527) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Makes the graph examples look a lil bit nicer and more compact. Note that this is a very recent thing that we can do this in Rust πŸ₯³ Also, embedds `graph_directed` in the examples (this has been done directly on the release branch already) * [x] full check passed in order to confirm the example output is still the same (tested this locally but who knows) --- .../rerun/archetypes/graph_edges.fbs | 2 +- .../rerun/archetypes/graph_nodes.fbs | 2 +- .../re_types/src/archetypes/graph_edges.rs | 30 +++++++++++++++++++ .../re_types/src/archetypes/graph_nodes.rs | 30 +++++++++++++++++++ .../all/archetypes/graph_directed.cpp | 7 +---- .../snippets/all/archetypes/graph_directed.py | 3 -- .../snippets/all/archetypes/graph_directed.rs | 14 ++++----- .../all/archetypes/graph_undirected.cpp | 7 +---- .../all/archetypes/graph_undirected.py | 9 +++--- .../all/archetypes/graph_undirected.rs | 16 +++++----- .../src/rerun/archetypes/graph_edges.hpp | 24 +++++++++++++++ .../src/rerun/archetypes/graph_nodes.hpp | 24 +++++++++++++++ .../rerun_sdk/rerun/archetypes/graph_edges.py | 27 +++++++++++++++++ .../rerun_sdk/rerun/archetypes/graph_nodes.py | 27 +++++++++++++++++ 14 files changed, 185 insertions(+), 37 deletions(-) diff --git a/crates/store/re_types/definitions/rerun/archetypes/graph_edges.fbs b/crates/store/re_types/definitions/rerun/archetypes/graph_edges.fbs index a20ea2d39fa1..337787158f71 100644 --- a/crates/store/re_types/definitions/rerun/archetypes/graph_edges.fbs +++ b/crates/store/re_types/definitions/rerun/archetypes/graph_edges.fbs @@ -7,7 +7,7 @@ namespace rerun.archetypes; /// By default, edges are undirected. /// /// \example archetypes/graph_undirected !api title="Simple undirected graph" image="https://static.rerun.io/graph_undirected/15f46bec77452a8c6220558e4403b99cac188e2e/1200w.png" -/// \example archetypes/graph_directed !api title="Simple directed graph" image="https://static.rerun.io/graph_directed/ca29a37b65e1e0b6482251dce401982a0bc568fa/1200w.png" +/// \example archetypes/graph_directed title="Simple directed graph" image="https://static.rerun.io/graph_directed/ca29a37b65e1e0b6482251dce401982a0bc568fa/1200w.png" table GraphEdges ( "attr.docs.category": "Graph", "attr.docs.unreleased", diff --git a/crates/store/re_types/definitions/rerun/archetypes/graph_nodes.fbs b/crates/store/re_types/definitions/rerun/archetypes/graph_nodes.fbs index 7e7ddb535164..142a88dd2444 100644 --- a/crates/store/re_types/definitions/rerun/archetypes/graph_nodes.fbs +++ b/crates/store/re_types/definitions/rerun/archetypes/graph_nodes.fbs @@ -5,7 +5,7 @@ namespace rerun.archetypes; /// A list of nodes in a graph with optional labels, colors, etc. /// /// \example archetypes/graph_undirected !api title="Simple undirected graph" image="https://static.rerun.io/graph_undirected/15f46bec77452a8c6220558e4403b99cac188e2e/1200w.png" -/// \example archetypes/graph_directed !api title="Simple directed graph" image="https://static.rerun.io/graph_directed/ca29a37b65e1e0b6482251dce401982a0bc568fa/1200w.png" +/// \example archetypes/graph_directed title="Simple directed graph" image="https://static.rerun.io/graph_directed/ca29a37b65e1e0b6482251dce401982a0bc568fa/1200w.png" table GraphNodes ( "attr.docs.category": "Graph", "attr.docs.unreleased", diff --git a/crates/store/re_types/src/archetypes/graph_edges.rs b/crates/store/re_types/src/archetypes/graph_edges.rs index a4aee2905982..d30dfea19a76 100644 --- a/crates/store/re_types/src/archetypes/graph_edges.rs +++ b/crates/store/re_types/src/archetypes/graph_edges.rs @@ -23,6 +23,36 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; /// By default, edges are undirected. /// /// ⚠️ **This type is experimental and may be removed in future versions** +/// +/// ## Example +/// +/// ### Simple directed graph +/// ```ignore +/// fn main() -> Result<(), Box> { +/// let rec = rerun::RecordingStreamBuilder::new("rerun_example_graph_directed").spawn()?; +/// +/// rec.log( +/// "simple", +/// &[ +/// &rerun::GraphNodes::new(["a", "b", "c"]) +/// .with_positions([(0.0, 100.0), (-100.0, 0.0), (100.0, 0.0)]) +/// .with_labels(["A", "B", "C"]) as &dyn rerun::AsComponents, +/// &rerun::GraphEdges::new([("a", "b"), ("b", "c"), ("c", "a")]).with_directed_edges(), +/// ], +/// )?; +/// +/// Ok(()) +/// } +/// ``` +///
+/// +/// +/// +/// +/// +/// +/// +///
#[derive(Clone, Debug, PartialEq, Eq)] pub struct GraphEdges { /// A list of node tuples. diff --git a/crates/store/re_types/src/archetypes/graph_nodes.rs b/crates/store/re_types/src/archetypes/graph_nodes.rs index 7a2c73d84601..3f3e707e185f 100644 --- a/crates/store/re_types/src/archetypes/graph_nodes.rs +++ b/crates/store/re_types/src/archetypes/graph_nodes.rs @@ -21,6 +21,36 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; /// **Archetype**: A list of nodes in a graph with optional labels, colors, etc. /// /// ⚠️ **This type is experimental and may be removed in future versions** +/// +/// ## Example +/// +/// ### Simple directed graph +/// ```ignore +/// fn main() -> Result<(), Box> { +/// let rec = rerun::RecordingStreamBuilder::new("rerun_example_graph_directed").spawn()?; +/// +/// rec.log( +/// "simple", +/// &[ +/// &rerun::GraphNodes::new(["a", "b", "c"]) +/// .with_positions([(0.0, 100.0), (-100.0, 0.0), (100.0, 0.0)]) +/// .with_labels(["A", "B", "C"]) as &dyn rerun::AsComponents, +/// &rerun::GraphEdges::new([("a", "b"), ("b", "c"), ("c", "a")]).with_directed_edges(), +/// ], +/// )?; +/// +/// Ok(()) +/// } +/// ``` +///
+/// +/// +/// +/// +/// +/// +/// +///
#[derive(Clone, Debug, PartialEq)] pub struct GraphNodes { /// A list of node IDs. diff --git a/docs/snippets/all/archetypes/graph_directed.cpp b/docs/snippets/all/archetypes/graph_directed.cpp index 3f09463b0eac..97b902d7bb4d 100644 --- a/docs/snippets/all/archetypes/graph_directed.cpp +++ b/docs/snippets/all/archetypes/graph_directed.cpp @@ -10,12 +10,7 @@ int main() { "simple", rerun::GraphNodes({"a", "b", "c"}) .with_positions({{0.0, 100.0}, {-100.0, 0.0}, {100.0, 0.0}}) - .with_labels({"A", "B", "C"}) - ); - - // Note: We log to the same entity here. - rec.log( - "simple", + .with_labels({"A", "B", "C"}), rerun::GraphEdges({{"a", "b"}, {"b", "c"}, {"c", "a"}}) // Graphs are undirected by default. .with_graph_type(rerun::components::GraphType::Directed) diff --git a/docs/snippets/all/archetypes/graph_directed.py b/docs/snippets/all/archetypes/graph_directed.py index 63a803138a3b..d4471994c178 100644 --- a/docs/snippets/all/archetypes/graph_directed.py +++ b/docs/snippets/all/archetypes/graph_directed.py @@ -9,8 +9,5 @@ rr.GraphNodes( node_ids=["a", "b", "c"], positions=[(0.0, 100.0), (-100.0, 0.0), (100.0, 0.0)], labels=["A", "B", "C"] ), -) -rr.log( - "simple", rr.GraphEdges(edges=[("a", "b"), ("b", "c"), ("c", "a")], graph_type="directed"), ) diff --git a/docs/snippets/all/archetypes/graph_directed.rs b/docs/snippets/all/archetypes/graph_directed.rs index be05ad8bd407..8a411238fb45 100644 --- a/docs/snippets/all/archetypes/graph_directed.rs +++ b/docs/snippets/all/archetypes/graph_directed.rs @@ -5,14 +5,12 @@ fn main() -> Result<(), Box> { rec.log( "simple", - &rerun::GraphNodes::new(["a", "b", "c"]) - .with_positions([(0.0, 100.0), (-100.0, 0.0), (100.0, 0.0)]) - .with_labels(["A", "B", "C"]), - )?; - // Note: We log to the same entity here. - rec.log( - "simple", - &rerun::GraphEdges::new([("a", "b"), ("b", "c"), ("c", "a")]).with_directed_edges(), + &[ + &rerun::GraphNodes::new(["a", "b", "c"]) + .with_positions([(0.0, 100.0), (-100.0, 0.0), (100.0, 0.0)]) + .with_labels(["A", "B", "C"]) as &dyn rerun::AsComponents, + &rerun::GraphEdges::new([("a", "b"), ("b", "c"), ("c", "a")]).with_directed_edges(), + ], )?; Ok(()) diff --git a/docs/snippets/all/archetypes/graph_undirected.cpp b/docs/snippets/all/archetypes/graph_undirected.cpp index 2d7e82ddba24..e81fecf36655 100644 --- a/docs/snippets/all/archetypes/graph_undirected.cpp +++ b/docs/snippets/all/archetypes/graph_undirected.cpp @@ -10,12 +10,7 @@ int main() { "simple", rerun::GraphNodes({"a", "b", "c"}) .with_positions({{0.0, 100.0}, {-100.0, 0.0}, {100.0, 0.0}}) - .with_labels({"A", "B", "C"}) - ); - - // Note: We log to the same entity here. - rec.log( - "simple", + .with_labels({"A", "B", "C"}), rerun::GraphEdges({{"a", "b"}, {"b", "c"}, {"c", "a"}}) // Optional: graphs are undirected by default. .with_graph_type(rerun::components::GraphType::Undirected) diff --git a/docs/snippets/all/archetypes/graph_undirected.py b/docs/snippets/all/archetypes/graph_undirected.py index 2397bfc31c5b..556a3782cfc0 100644 --- a/docs/snippets/all/archetypes/graph_undirected.py +++ b/docs/snippets/all/archetypes/graph_undirected.py @@ -9,8 +9,9 @@ rr.GraphNodes( node_ids=["a", "b", "c"], positions=[(0.0, 100.0), (-100.0, 0.0), (100.0, 0.0)], labels=["A", "B", "C"] ), -) -rr.log( - "simple", - rr.GraphEdges(edges=[("a", "b"), ("b", "c"), ("c", "a")], graph_type="undirected"), + rr.GraphEdges( + edges=[("a", "b"), ("b", "c"), ("c", "a")], + # Optional: graphs are undirected by default. + graph_type="undirected", + ), ) diff --git a/docs/snippets/all/archetypes/graph_undirected.rs b/docs/snippets/all/archetypes/graph_undirected.rs index affd0ec3d0ee..c87219a931f2 100644 --- a/docs/snippets/all/archetypes/graph_undirected.rs +++ b/docs/snippets/all/archetypes/graph_undirected.rs @@ -5,14 +5,14 @@ fn main() -> Result<(), Box> { rec.log( "simple", - &rerun::GraphNodes::new(["a", "b", "c"]) - .with_positions([(0.0, 100.0), (-100.0, 0.0), (100.0, 0.0)]) - .with_labels(["A", "B", "C"]), - )?; - // Note: We log to the same entity here. - rec.log( - "simple", - &rerun::GraphEdges::new([("a", "b"), ("b", "c"), ("c", "a")]).with_undirected_edges(), // Optional: graphs are undirected by default. + &[ + &rerun::GraphNodes::new(["a", "b", "c"]) + .with_positions([(0.0, 100.0), (-100.0, 0.0), (100.0, 0.0)]) + .with_labels(["A", "B", "C"]) as &dyn rerun::AsComponents, + &rerun::GraphEdges::new([("a", "b"), ("b", "c"), ("c", "a")]) + // Optional: graphs are undirected by default. + .with_undirected_edges(), + ], )?; Ok(()) diff --git a/rerun_cpp/src/rerun/archetypes/graph_edges.hpp b/rerun_cpp/src/rerun/archetypes/graph_edges.hpp index 4e60d8e23d82..a19940a3a351 100644 --- a/rerun_cpp/src/rerun/archetypes/graph_edges.hpp +++ b/rerun_cpp/src/rerun/archetypes/graph_edges.hpp @@ -21,6 +21,30 @@ namespace rerun::archetypes { /// /// By default, edges are undirected. /// + /// ## Example + /// + /// ### Simple directed graph + /// ![image](https://static.rerun.io/graph_directed/ca29a37b65e1e0b6482251dce401982a0bc568fa/full.png) + /// + /// ```cpp + /// #include + /// + /// int main() { + /// const auto rec = rerun::RecordingStream("rerun_example_graph_directed"); + /// rec.spawn().exit_on_failure(); + /// + /// rec.log( + /// "simple", + /// rerun::GraphNodes({"a", "b", "c"}) + /// .with_positions({{0.0, 100.0}, {-100.0, 0.0}, {100.0, 0.0}}) + /// .with_labels({"A", "B", "C"}), + /// rerun::GraphEdges({{"a", "b"}, {"b", "c"}, {"c", "a"}}) + /// // Graphs are undirected by default. + /// .with_graph_type(rerun::components::GraphType::Directed) + /// ); + /// } + /// ``` + /// /// ⚠ **This is an experimental API! It is not fully supported, and is likely to change significantly in future versions.** struct GraphEdges { /// A list of node tuples. diff --git a/rerun_cpp/src/rerun/archetypes/graph_nodes.hpp b/rerun_cpp/src/rerun/archetypes/graph_nodes.hpp index 1323569a7137..3ee519b9e729 100644 --- a/rerun_cpp/src/rerun/archetypes/graph_nodes.hpp +++ b/rerun_cpp/src/rerun/archetypes/graph_nodes.hpp @@ -23,6 +23,30 @@ namespace rerun::archetypes { /// **Archetype**: A list of nodes in a graph with optional labels, colors, etc. /// + /// ## Example + /// + /// ### Simple directed graph + /// ![image](https://static.rerun.io/graph_directed/ca29a37b65e1e0b6482251dce401982a0bc568fa/full.png) + /// + /// ```cpp + /// #include + /// + /// int main() { + /// const auto rec = rerun::RecordingStream("rerun_example_graph_directed"); + /// rec.spawn().exit_on_failure(); + /// + /// rec.log( + /// "simple", + /// rerun::GraphNodes({"a", "b", "c"}) + /// .with_positions({{0.0, 100.0}, {-100.0, 0.0}, {100.0, 0.0}}) + /// .with_labels({"A", "B", "C"}), + /// rerun::GraphEdges({{"a", "b"}, {"b", "c"}, {"c", "a"}}) + /// // Graphs are undirected by default. + /// .with_graph_type(rerun::components::GraphType::Directed) + /// ); + /// } + /// ``` + /// /// ⚠ **This is an experimental API! It is not fully supported, and is likely to change significantly in future versions.** struct GraphNodes { /// A list of node IDs. diff --git a/rerun_py/rerun_sdk/rerun/archetypes/graph_edges.py b/rerun_py/rerun_sdk/rerun/archetypes/graph_edges.py index 4fa4c6017d9b..a1568b980108 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/graph_edges.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/graph_edges.py @@ -26,6 +26,33 @@ class GraphEdges(Archetype): By default, edges are undirected. ⚠️ **This is an experimental API! It is not fully supported, and is likely to change significantly in future versions.** + + Example + ------- + ### Simple directed graph: + ```python + import rerun as rr + + rr.init("rerun_example_graph_directed", spawn=True) + + rr.log( + "simple", + rr.GraphNodes( + node_ids=["a", "b", "c"], positions=[(0.0, 100.0), (-100.0, 0.0), (100.0, 0.0)], labels=["A", "B", "C"] + ), + rr.GraphEdges(edges=[("a", "b"), ("b", "c"), ("c", "a")], graph_type="directed"), + ) + ``` +
+ + + + + + + +
+ """ def __init__(self: Any, edges: datatypes.Utf8PairArrayLike, *, graph_type: components.GraphTypeLike | None = None): diff --git a/rerun_py/rerun_sdk/rerun/archetypes/graph_nodes.py b/rerun_py/rerun_sdk/rerun/archetypes/graph_nodes.py index bed4372bbaad..13426e12ae29 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/graph_nodes.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/graph_nodes.py @@ -24,6 +24,33 @@ class GraphNodes(Archetype): **Archetype**: A list of nodes in a graph with optional labels, colors, etc. ⚠️ **This is an experimental API! It is not fully supported, and is likely to change significantly in future versions.** + + Example + ------- + ### Simple directed graph: + ```python + import rerun as rr + + rr.init("rerun_example_graph_directed", spawn=True) + + rr.log( + "simple", + rr.GraphNodes( + node_ids=["a", "b", "c"], positions=[(0.0, 100.0), (-100.0, 0.0), (100.0, 0.0)], labels=["A", "B", "C"] + ), + rr.GraphEdges(edges=[("a", "b"), ("b", "c"), ("c", "a")], graph_type="directed"), + ) + ``` +
+ + + + + + + +
+ """ def __init__( From 5b62c37d940351fdf7845229fa084866bbb8f777 Mon Sep 17 00:00:00 2001 From: Jeremy Leibs Date: Wed, 18 Dec 2024 13:41:51 +0100 Subject: [PATCH 22/30] Add docstring about need for `include_indicator_columns=True` (#8528) ### Related - https://github.com/rerun-io/rerun/issues/8522 ### What Explains how to avoid hitting an issue. --- rerun_py/rerun_sdk/rerun/dataframe.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/rerun_py/rerun_sdk/rerun/dataframe.py b/rerun_py/rerun_sdk/rerun/dataframe.py index b525bf1e9e81..777a962b6b72 100644 --- a/rerun_py/rerun_sdk/rerun/dataframe.py +++ b/rerun_py/rerun_sdk/rerun/dataframe.py @@ -77,7 +77,13 @@ def as_arrow_array(self) -> pa.Array: def send_record_batch(batch: pa.RecordBatch, rec: Optional[RecordingStream] = None) -> None: - """Coerce a single pyarrow `RecordBatch` to Rerun structure.""" + """ + Coerce a single pyarrow `RecordBatch` to Rerun structure. + + If this `RecordBatch` came from a call to [`RecordingView.view`][rerun.dataframe.RecordingView.view], you + will want to make sure the `view` call includes `include_indicator_columns = True` or else the + viewer will not know about the archetypes in the data. + """ indexes = [] data: defaultdict[str, list[Any]] = defaultdict(list) @@ -112,7 +118,14 @@ def send_record_batch(batch: pa.RecordBatch, rec: Optional[RecordingStream] = No def send_dataframe(df: pa.RecordBatchReader | pa.Table, rec: Optional[RecordingStream] = None) -> None: - """Coerce a pyarrow `RecordBatchReader` or `Table` to Rerun structure.""" + """ + Coerce a pyarrow `RecordBatchReader` or `Table` to Rerun structure. + + If this `Table` came from a call to [`RecordingView.view`][rerun.dataframe.RecordingView.view], you + will want to make sure the `view` call includes `include_indicator_columns = True` or else the + viewer will not know about the archetypes in the data. + + """ if isinstance(df, pa.Table): df = df.to_reader() From e9d047615a8ed07dbe4425bcfbfffc183aeabf6b Mon Sep 17 00:00:00 2001 From: Antoine Beyeler <49431240+abey79@users.noreply.github.com> Date: Wed, 18 Dec 2024 14:59:36 +0100 Subject: [PATCH 23/30] Enable GH releases for RC (#8524) This PR enables the creation of GH releases (as draft and marked as pre-release) for RCs. Motivations for doing so: - test that part of the workflow, in particular that all binaries are correctly produced - test the binary using `cargo binstall` - these releases a single-click deletable from GH (if we want to do so) - GH releases marked as "pre-release" aren't displayed in the GH project page Pending questions: do we want that? what about alphas? --- .github/workflows/release.yml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d046c9cfedc2..ec762a5278db 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -321,7 +321,7 @@ jobs: github-release: name: "GitHub Release" - if: inputs.release-type == 'final' + if: inputs.release-type == 'rc' || inputs.release-type == 'final' needs: [ version, @@ -347,9 +347,16 @@ jobs: run: | version="${{ needs.version.outputs.final }}" commit="${{ needs.version.outputs.release-commit }}" + + if [ ${{ inputs.release-type }} = "final" ]; then + pre_arg="" + else + pre_arg="--prerelease" + fi + git tag $version $commit git push origin $version - gh release create $version --verify-tag --draft --title $version + gh release create $version --verify-tag --draft --title $version $pre_arg - name: Create comment env: From 879e531ae8b2026b71fb3255f6d324691552a863 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Wed, 18 Dec 2024 15:00:34 +0100 Subject: [PATCH 24/30] Tensor shape and dimension names as separate arrow fields (#8376) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### Related * Closes https://github.com/rerun-io/rerun/issues/6830 ### What ⚠️ Breaks tensors in .rrd files! In `TensorData` we used to have `shape: [TensorDimension]` with `struct TensorDimension { size: u64, name: Option }`. Now `TensorData` has `shape: [u64], names: Option<[String]>` instead. So basically a AoS -> SoA change ### TODO * [x] Port Python * [x] Port C++ * [x] Document in migration guide * [x] Run `@rerun-bot full-check` --------- Co-authored-by: Antoine Beyeler --- crates/store/re_chunk/src/iter.rs | 2 +- .../re_types/definitions/rerun/datatypes.fbs | 1 - .../rerun/datatypes/tensor_data.fbs | 13 +- .../rerun/datatypes/tensor_dimension.fbs | 15 - .../src/archetypes/depth_image_ext.rs | 10 +- .../re_types/src/archetypes/image_ext.rs | 16 +- .../src/archetypes/segmentation_image_ext.rs | 10 +- .../re_types/src/archetypes/tensor_ext.rs | 41 +-- .../re_types/src/datatypes/.gitattributes | 1 - crates/store/re_types/src/datatypes/mod.rs | 3 - .../re_types/src/datatypes/tensor_data.rs | 246 ++++++++++++++-- .../re_types/src/datatypes/tensor_data_ext.rs | 137 +++++---- .../src/datatypes/tensor_dimension.rs | 266 ------------------ .../src/datatypes/tensor_dimension_ext.rs | 60 ---- crates/store/re_types/src/image.rs | 20 +- crates/store/re_types/tests/types/tensor.rs | 75 +---- .../store/re_types_core/src/arrow_buffer.rs | 10 + crates/top/rerun/src/commands/rrd/compare.rs | 4 + crates/top/rerun/src/lib.rs | 8 +- crates/top/rerun/src/sdk.rs | 2 +- crates/viewer/re_data_ui/src/tensor.rs | 39 +-- .../re_view_tensor/src/dimension_mapping.rs | 7 +- crates/viewer/re_view_tensor/src/lib.rs | 35 ++- .../src/tensor_dimension_mapper.rs | 5 +- .../viewer/re_view_tensor/src/tensor_tests.rs | 2 +- .../viewer/re_view_tensor/src/view_class.rs | 44 ++- .../reference/migration/migration-0-21.md | 3 + .../reference/types/components/tensor_data.md | 6 +- docs/content/reference/types/datatypes.md | 1 - .../reference/types/datatypes/.gitattributes | 1 - .../reference/types/datatypes/tensor_data.md | 21 +- .../types/datatypes/tensor_dimension.md | 36 --- docs/snippets/README.md | 6 +- rerun_cpp/src/rerun.hpp | 1 - rerun_cpp/src/rerun/archetypes/tensor.hpp | 4 +- rerun_cpp/src/rerun/archetypes/tensor_ext.cpp | 10 +- .../src/rerun/components/tensor_data.hpp | 7 +- .../src/rerun/components/tensor_data_ext.cpp | 4 +- rerun_cpp/src/rerun/datatypes.hpp | 1 - rerun_cpp/src/rerun/datatypes/.gitattributes | 2 - rerun_cpp/src/rerun/datatypes/tensor_data.cpp | 47 ++-- rerun_cpp/src/rerun/datatypes/tensor_data.hpp | 24 +- .../src/rerun/datatypes/tensor_data_ext.cpp | 6 +- .../src/rerun/datatypes/tensor_dimension.cpp | 77 ----- .../src/rerun/datatypes/tensor_dimension.hpp | 66 ----- .../rerun/datatypes/tensor_dimension_ext.cpp | 21 -- rerun_py/README.md | 5 + rerun_py/rerun_sdk/rerun/_validators.py | 9 +- .../rerun/archetypes/bar_chart_ext.py | 2 +- .../rerun_sdk/rerun/archetypes/tensor_ext.py | 8 +- .../rerun_sdk/rerun/datatypes/.gitattributes | 1 - .../rerun_sdk/rerun/datatypes/__init__.py | 5 - .../rerun_sdk/rerun/datatypes/tensor_data.py | 37 +-- .../rerun/datatypes/tensor_data_ext.py | 87 +++--- .../rerun/datatypes/tensor_dimension.py | 71 ----- rerun_py/tests/unit/test_tensor.py | 41 +-- tests/cpp/roundtrips/tensor/main.cpp | 4 +- .../check_all_components_ui.py | 2 +- 58 files changed, 637 insertions(+), 1051 deletions(-) delete mode 100644 crates/store/re_types/definitions/rerun/datatypes/tensor_dimension.fbs delete mode 100644 crates/store/re_types/src/datatypes/tensor_dimension.rs delete mode 100644 crates/store/re_types/src/datatypes/tensor_dimension_ext.rs delete mode 100644 docs/content/reference/types/datatypes/tensor_dimension.md delete mode 100644 rerun_cpp/src/rerun/datatypes/tensor_dimension.cpp delete mode 100644 rerun_cpp/src/rerun/datatypes/tensor_dimension.hpp delete mode 100644 rerun_cpp/src/rerun/datatypes/tensor_dimension_ext.cpp delete mode 100644 rerun_py/rerun_sdk/rerun/datatypes/tensor_dimension.py diff --git a/crates/store/re_chunk/src/iter.rs b/crates/store/re_chunk/src/iter.rs index 571c5995c48b..1534d9ac0a28 100644 --- a/crates/store/re_chunk/src/iter.rs +++ b/crates/store/re_chunk/src/iter.rs @@ -710,7 +710,7 @@ impl Chunk { Err(err) => { if cfg!(debug_assertions) { panic!( - "deserialization failed for {}, data discarded: {}", + "[DEBUG-ONLY] deserialization failed for {}, data discarded: {}", C::name(), re_error::format_ref(&err), ); diff --git a/crates/store/re_types/definitions/rerun/datatypes.fbs b/crates/store/re_types/definitions/rerun/datatypes.fbs index 5772f4c3b8d5..fa325413e155 100644 --- a/crates/store/re_types/definitions/rerun/datatypes.fbs +++ b/crates/store/re_types/definitions/rerun/datatypes.fbs @@ -27,7 +27,6 @@ include "./datatypes/rgba32.fbs"; include "./datatypes/rotation_axis_angle.fbs"; include "./datatypes/tensor_buffer.fbs"; include "./datatypes/tensor_data.fbs"; -include "./datatypes/tensor_dimension.fbs"; include "./datatypes/tensor_dimension_selection.fbs"; include "./datatypes/time_int.fbs"; include "./datatypes/uint16.fbs"; diff --git a/crates/store/re_types/definitions/rerun/datatypes/tensor_data.fbs b/crates/store/re_types/definitions/rerun/datatypes/tensor_data.fbs index 1624be6e00f3..6301c33c7abb 100644 --- a/crates/store/re_types/definitions/rerun/datatypes/tensor_data.fbs +++ b/crates/store/re_types/definitions/rerun/datatypes/tensor_data.fbs @@ -19,8 +19,17 @@ table TensorData ( "attr.python.array_aliases": "npt.ArrayLike", "attr.rust.derive": "PartialEq," ) { - /// The shape of the tensor, including optional names for each dimension. - shape: [rerun.datatypes.TensorDimension] (order: 200); + /// The shape of the tensor, i.e. the length of each dimension. + shape: [uint64] (order: 200); + + /// The names of the dimensions of the tensor (optional). + /// + /// If set, should be the same length as [datatypes.TensorData.shape]. + /// If it has a different length your names may show up improperly, + /// and some constructors may produce a warning or even an error. + /// + /// Example: `["height", "width", "channel", "batch"]`. + names: [string] (order: 250, nullable); /// The content/data. buffer: rerun.datatypes.TensorBuffer (order: 300); diff --git a/crates/store/re_types/definitions/rerun/datatypes/tensor_dimension.fbs b/crates/store/re_types/definitions/rerun/datatypes/tensor_dimension.fbs deleted file mode 100644 index 7d755a8b81e5..000000000000 --- a/crates/store/re_types/definitions/rerun/datatypes/tensor_dimension.fbs +++ /dev/null @@ -1,15 +0,0 @@ -namespace rerun.datatypes; - -// --- - -/// A single dimension within a multi-dimensional tensor. -// TODO(jleibs): Support for stride. -table TensorDimension ( - "attr.rust.derive_only": "Clone, Default, Eq, PartialEq" -) { - /// The length of this dimension. - size: ulong (order: 100); - - /// The name of this dimension, e.g. "width", "height", "channel", "batch', …. - name: string (order: 200, nullable); -} diff --git a/crates/store/re_types/src/archetypes/depth_image_ext.rs b/crates/store/re_types/src/archetypes/depth_image_ext.rs index b1c7044c0914..af72285a3edd 100644 --- a/crates/store/re_types/src/archetypes/depth_image_ext.rs +++ b/crates/store/re_types/src/archetypes/depth_image_ext.rs @@ -20,7 +20,7 @@ impl DepthImage { let tensor_data: TensorData = data .try_into() .map_err(ImageConstructionError::TensorDataConversion)?; - let shape = tensor_data.shape; + let TensorData { shape, buffer, .. } = tensor_data; let non_empty_dim_inds = find_non_empty_dim_indices(&shape); @@ -28,13 +28,11 @@ impl DepthImage { return Err(ImageConstructionError::BadImageShape(shape)); } - let (blob, datatype) = blob_and_datatype_from_tensor(tensor_data.buffer); + let (blob, datatype) = blob_and_datatype_from_tensor(buffer); - let (height, width) = (&shape[non_empty_dim_inds[0]], &shape[non_empty_dim_inds[1]]); - let height = height.size as u32; - let width = width.size as u32; + let (height, width) = (shape[non_empty_dim_inds[0]], shape[non_empty_dim_inds[1]]); - let image_format = ImageFormat::depth([width, height], datatype); + let image_format = ImageFormat::depth([width as u32, height as u32], datatype); Ok(Self { buffer: blob.into(), diff --git a/crates/store/re_types/src/archetypes/image_ext.rs b/crates/store/re_types/src/archetypes/image_ext.rs index 1beff5061887..0304cecb27fe 100644 --- a/crates/store/re_types/src/archetypes/image_ext.rs +++ b/crates/store/re_types/src/archetypes/image_ext.rs @@ -33,17 +33,17 @@ impl Image { let tensor_data: TensorData = data .try_into() .map_err(ImageConstructionError::TensorDataConversion)?; - let shape = tensor_data.shape; + let TensorData { shape, buffer, .. } = tensor_data; let non_empty_dim_inds = find_non_empty_dim_indices(&shape); let is_shape_correct = match color_model { ColorModel::L => non_empty_dim_inds.len() == 2, ColorModel::RGB | ColorModel::BGR => { - non_empty_dim_inds.len() == 3 && shape[non_empty_dim_inds[2]].size == 3 + non_empty_dim_inds.len() == 3 && shape[non_empty_dim_inds[2]] == 3 } ColorModel::RGBA | ColorModel::BGRA => { - non_empty_dim_inds.len() == 3 && shape[non_empty_dim_inds[2]].size == 4 + non_empty_dim_inds.len() == 3 && shape[non_empty_dim_inds[2]] == 4 } }; @@ -51,15 +51,13 @@ impl Image { return Err(ImageConstructionError::BadImageShape(shape)); } - let (blob, datatype) = blob_and_datatype_from_tensor(tensor_data.buffer); + let (blob, datatype) = blob_and_datatype_from_tensor(buffer); - let (height, width) = (&shape[non_empty_dim_inds[0]], &shape[non_empty_dim_inds[1]]); - let height = height.size as u32; - let width = width.size as u32; + let (height, width) = (shape[non_empty_dim_inds[0]], shape[non_empty_dim_inds[1]]); let image_format = ImageFormat { - width, - height, + width: width as _, + height: height as _, pixel_format: None, channel_datatype: Some(datatype), color_model: Some(color_model), diff --git a/crates/store/re_types/src/archetypes/segmentation_image_ext.rs b/crates/store/re_types/src/archetypes/segmentation_image_ext.rs index 4c2f71375b39..a90856eb24d3 100644 --- a/crates/store/re_types/src/archetypes/segmentation_image_ext.rs +++ b/crates/store/re_types/src/archetypes/segmentation_image_ext.rs @@ -19,7 +19,7 @@ impl SegmentationImage { let tensor_data: TensorData = data .try_into() .map_err(ImageConstructionError::TensorDataConversion)?; - let shape = tensor_data.shape; + let TensorData { shape, buffer, .. } = tensor_data; let non_empty_dim_inds = find_non_empty_dim_indices(&shape); @@ -27,13 +27,11 @@ impl SegmentationImage { return Err(ImageConstructionError::BadImageShape(shape)); } - let (blob, datatype) = blob_and_datatype_from_tensor(tensor_data.buffer); + let (blob, datatype) = blob_and_datatype_from_tensor(buffer); - let (height, width) = (&shape[non_empty_dim_inds[0]], &shape[non_empty_dim_inds[1]]); - let height = height.size as u32; - let width = width.size as u32; + let (height, width) = (shape[non_empty_dim_inds[0]], shape[non_empty_dim_inds[1]]); - let image_format = ImageFormat::segmentation([width, height], datatype); + let image_format = ImageFormat::segmentation([width as _, height as _], datatype); Ok(Self { buffer: blob.into(), diff --git a/crates/store/re_types/src/archetypes/tensor_ext.rs b/crates/store/re_types/src/archetypes/tensor_ext.rs index c7063b0b6264..2bfa7c1f08ef 100644 --- a/crates/store/re_types/src/archetypes/tensor_ext.rs +++ b/crates/store/re_types/src/archetypes/tensor_ext.rs @@ -1,4 +1,4 @@ -use crate::datatypes::{TensorData, TensorDimension}; +use crate::datatypes::TensorData; use re_types_core::ArrowString; @@ -24,37 +24,16 @@ impl Tensor { /// Update the `names` of the contained [`TensorData`] dimensions. /// - /// Any existing Dimension names will be overwritten. + /// Any existing names will be overwritten. /// - /// If too many, or too few names are provided, this function will warn and only - /// update the subset of names that it can. - pub fn with_dim_names(self, names: impl IntoIterator>) -> Self { - let names: Vec<_> = names.into_iter().map(|x| Some(x.into())).collect(); - if names.len() != self.data.0.shape.len() { - re_log::warn_once!( - "Wrong number of names provided for tensor dimension. {} provided but {} expected.", - names.len(), - self.data.0.shape.len(), - ); - } - Self { - data: TensorData { - shape: self - .data - .0 - .shape - .into_iter() - .zip(names.into_iter().chain(std::iter::repeat(None))) - .map(|(dim, name)| TensorDimension { - size: dim.size, - name: name.or(dim.name), - }) - .collect(), - buffer: self.data.0.buffer, - } - .into(), - value_range: None, - } + /// If the wrong number of names are given, a warning will be logged, + /// and the names might not show up correctly. + pub fn with_dim_names( + mut self, + names: impl IntoIterator>, + ) -> Self { + self.data.0 = self.data.0.with_dim_names(names); + self } } diff --git a/crates/store/re_types/src/datatypes/.gitattributes b/crates/store/re_types/src/datatypes/.gitattributes index 289cbd45793c..5995b6d6c716 100644 --- a/crates/store/re_types/src/datatypes/.gitattributes +++ b/crates/store/re_types/src/datatypes/.gitattributes @@ -25,7 +25,6 @@ rgba32.rs linguist-generated=true rotation_axis_angle.rs linguist-generated=true tensor_buffer.rs linguist-generated=true tensor_data.rs linguist-generated=true -tensor_dimension.rs linguist-generated=true tensor_dimension_index_selection.rs linguist-generated=true tensor_dimension_selection.rs linguist-generated=true utf8pair.rs linguist-generated=true diff --git a/crates/store/re_types/src/datatypes/mod.rs b/crates/store/re_types/src/datatypes/mod.rs index d1edf377eb08..f18d728fd794 100644 --- a/crates/store/re_types/src/datatypes/mod.rs +++ b/crates/store/re_types/src/datatypes/mod.rs @@ -46,8 +46,6 @@ mod tensor_buffer; mod tensor_buffer_ext; mod tensor_data; mod tensor_data_ext; -mod tensor_dimension; -mod tensor_dimension_ext; mod tensor_dimension_index_selection; mod tensor_dimension_selection; mod tensor_dimension_selection_ext; @@ -95,7 +93,6 @@ pub use self::rgba32::Rgba32; pub use self::rotation_axis_angle::RotationAxisAngle; pub use self::tensor_buffer::TensorBuffer; pub use self::tensor_data::TensorData; -pub use self::tensor_dimension::TensorDimension; pub use self::tensor_dimension_index_selection::TensorDimensionIndexSelection; pub use self::tensor_dimension_selection::TensorDimensionSelection; pub use self::utf8pair::Utf8Pair; diff --git a/crates/store/re_types/src/datatypes/tensor_data.rs b/crates/store/re_types/src/datatypes/tensor_data.rs index 0d19cb6190a6..4d75cc0c12e3 100644 --- a/crates/store/re_types/src/datatypes/tensor_data.rs +++ b/crates/store/re_types/src/datatypes/tensor_data.rs @@ -28,8 +28,17 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; /// which stores a contiguous array of typed values. #[derive(Clone, Debug, PartialEq)] pub struct TensorData { - /// The shape of the tensor, including optional names for each dimension. - pub shape: Vec, + /// The shape of the tensor, i.e. the length of each dimension. + pub shape: ::re_types_core::ArrowBuffer, + + /// The names of the dimensions of the tensor (optional). + /// + /// If set, should be the same length as [`datatypes::TensorData::shape`][crate::datatypes::TensorData::shape]. + /// If it has a different length your names may show up improperly, + /// and some constructors may produce a warning or even an error. + /// + /// Example: `["height", "width", "channel", "batch"]`. + pub names: Option>, /// The content/data. pub buffer: crate::datatypes::TensorBuffer, @@ -47,11 +56,20 @@ impl ::re_types_core::Loggable for TensorData { "shape", DataType::List(std::sync::Arc::new(Field::new( "item", - ::arrow_datatype(), + DataType::UInt64, false, ))), false, ), + Field::new( + "names", + DataType::List(std::sync::Arc::new(Field::new( + "item", + DataType::Utf8, + false, + ))), + true, + ), Field::new( "buffer", ::arrow_datatype(), @@ -76,11 +94,20 @@ impl ::re_types_core::Loggable for TensorData { "shape", DataType::List(std::sync::Arc::new(Field::new( "item", - ::arrow_datatype(), + DataType::UInt64, false, ))), false, ), + Field::new( + "names", + DataType::List(std::sync::Arc::new(Field::new( + "item", + DataType::Utf8, + false, + ))), + true, + ), Field::new( "buffer", ::arrow_datatype(), @@ -113,29 +140,73 @@ impl ::re_types_core::Loggable for TensorData { let any_nones = somes.iter().any(|some| !*some); any_nones.then(|| somes.into()) }; + { + let offsets = + arrow::buffer::OffsetBuffer::::from_lengths(shape.iter().map( + |opt| opt.as_ref().map_or(0, |datum| datum.num_instances()), + )); + let shape_inner_data: ScalarBuffer<_> = shape + .iter() + .flatten() + .map(|b| b.as_slice()) + .collect::>() + .concat() + .into(); + let shape_inner_validity: Option = None; + as_array_ref(ListArray::try_new( + std::sync::Arc::new(Field::new("item", DataType::UInt64, false)), + offsets, + as_array_ref(PrimitiveArray::::new( + shape_inner_data, + shape_inner_validity, + )), + shape_validity, + )?) + } + }, + { + let (somes, names): (Vec<_>, Vec<_>) = data + .iter() + .map(|datum| { + let datum = + datum.as_ref().map(|datum| datum.names.clone()).flatten(); + (datum.is_some(), datum) + }) + .unzip(); + let names_validity: Option = { + let any_nones = somes.iter().any(|some| !*some); + any_nones.then(|| somes.into()) + }; { let offsets = arrow::buffer::OffsetBuffer::::from_lengths( - shape + names .iter() .map(|opt| opt.as_ref().map_or(0, |datum| datum.len())), ); - let shape_inner_data: Vec<_> = - shape.into_iter().flatten().flatten().collect(); - let shape_inner_validity: Option = None; + let names_inner_data: Vec<_> = + names.into_iter().flatten().flatten().collect(); + let names_inner_validity: Option = None; as_array_ref(ListArray::try_new( - std::sync::Arc::new(Field::new( - "item", - ::arrow_datatype(), - false, - )), + std::sync::Arc::new(Field::new("item", DataType::Utf8, false)), offsets, { - _ = shape_inner_validity; - crate::datatypes::TensorDimension::to_arrow_opt( - shape_inner_data.into_iter().map(Some), - )? + let offsets = arrow::buffer::OffsetBuffer::::from_lengths( + names_inner_data.iter().map(|datum| datum.len()), + ); + let inner_data: arrow::buffer::Buffer = names_inner_data + .into_iter() + .flat_map(|s| s.into_arrow2_buffer()) + .collect(); + #[allow(unsafe_code, clippy::undocumented_unsafe_blocks)] + as_array_ref(unsafe { + StringArray::new_unchecked( + offsets, + inner_data, + names_inner_validity, + ) + }) }, - shape_validity, + names_validity, )?) } }, @@ -208,7 +279,7 @@ impl ::re_types_core::Loggable for TensorData { .ok_or_else(|| { let expected = DataType::List(std::sync::Arc::new(Field::new( "item", - ::arrow_datatype(), + DataType::UInt64, false, ))); let actual = arrow_data.data_type().clone(); @@ -220,10 +291,133 @@ impl ::re_types_core::Loggable for TensorData { } else { let arrow_data_inner = { let arrow_data_inner = &**arrow_data.values(); - crate::datatypes::TensorDimension::from_arrow2_opt(arrow_data_inner) + arrow_data_inner + .as_any() + .downcast_ref::() + .ok_or_else(|| { + let expected = DataType::UInt64; + let actual = arrow_data_inner.data_type().clone(); + DeserializationError::datatype_mismatch(expected, actual) + }) .with_context("rerun.datatypes.TensorData#shape")? + .values() + }; + let offsets = arrow_data.offsets(); + arrow2::bitmap::utils::ZipValidity::new_with_validity( + offsets.windows(2), + arrow_data.validity(), + ) + .map(|elem| { + elem.map(|window| { + let start = window[0] as usize; + let end = window[1] as usize; + if arrow_data_inner.len() < end { + return Err(DeserializationError::offset_slice_oob( + (start, end), + arrow_data_inner.len(), + )); + } + + #[allow(unsafe_code, clippy::undocumented_unsafe_blocks)] + let data = unsafe { + arrow_data_inner + .clone() + .sliced_unchecked(start, end - start) + }; + let data = ::re_types_core::ArrowBuffer::from(data); + Ok(data) + }) + .transpose() + }) + .collect::>>>()? + } + .into_iter() + } + }; + let names = { + if !arrays_by_name.contains_key("names") { + return Err(DeserializationError::missing_struct_field( + Self::arrow_datatype(), + "names", + )) + .with_context("rerun.datatypes.TensorData"); + } + let arrow_data = &**arrays_by_name["names"]; + { + let arrow_data = arrow_data + .as_any() + .downcast_ref::>() + .ok_or_else(|| { + let expected = DataType::List(std::sync::Arc::new(Field::new( + "item", + DataType::Utf8, + false, + ))); + let actual = arrow_data.data_type().clone(); + DeserializationError::datatype_mismatch(expected, actual) + }) + .with_context("rerun.datatypes.TensorData#names")?; + if arrow_data.is_empty() { + Vec::new() + } else { + let arrow_data_inner = { + let arrow_data_inner = &**arrow_data.values(); + { + let arrow_data_inner = arrow_data_inner + .as_any() + .downcast_ref::>() + .ok_or_else(|| { + let expected = DataType::Utf8; + let actual = arrow_data_inner.data_type().clone(); + DeserializationError::datatype_mismatch( + expected, actual, + ) + }) + .with_context("rerun.datatypes.TensorData#names")?; + let arrow_data_inner_buf = arrow_data_inner.values(); + let offsets = arrow_data_inner.offsets(); + arrow2::bitmap::utils::ZipValidity::new_with_validity( + offsets.windows(2), + arrow_data_inner.validity(), + ) + .map(|elem| { + elem.map(|window| { + let start = window[0] as usize; + let end = window[1] as usize; + let len = end - start; + if arrow_data_inner_buf.len() < end { + return Err( + DeserializationError::offset_slice_oob( + (start, end), + arrow_data_inner_buf.len(), + ), + ); + } + + #[allow( + unsafe_code, + clippy::undocumented_unsafe_blocks + )] + let data = unsafe { + arrow_data_inner_buf + .clone() + .sliced_unchecked(start, len) + }; + Ok(data) + }) + .transpose() + }) + .map(|res_or_opt| { + res_or_opt.map(|res_or_opt| { + res_or_opt + .map(|v| ::re_types_core::ArrowString::from(v)) + }) + }) + .collect::>>>() + .with_context("rerun.datatypes.TensorData#names")? .into_iter() - .collect::>() + } + .collect::>() }; let offsets = arrow_data.offsets(); arrow2::bitmap::utils::ZipValidity::new_with_validity( @@ -272,15 +466,16 @@ impl ::re_types_core::Loggable for TensorData { .into_iter() }; arrow2::bitmap::utils::ZipValidity::new_with_validity( - ::itertools::izip!(shape, buffer), + ::itertools::izip!(shape, names, buffer), arrow_data.validity(), ) .map(|opt| { - opt.map(|(shape, buffer)| { + opt.map(|(shape, names, buffer)| { Ok(Self { shape: shape .ok_or_else(DeserializationError::missing_data) .with_context("rerun.datatypes.TensorData#shape")?, + names, buffer: buffer .ok_or_else(DeserializationError::missing_data) .with_context("rerun.datatypes.TensorData#buffer")?, @@ -298,12 +493,13 @@ impl ::re_types_core::Loggable for TensorData { impl ::re_types_core::SizeBytes for TensorData { #[inline] fn heap_size_bytes(&self) -> u64 { - self.shape.heap_size_bytes() + self.buffer.heap_size_bytes() + self.shape.heap_size_bytes() + self.names.heap_size_bytes() + self.buffer.heap_size_bytes() } #[inline] fn is_pod() -> bool { - >::is_pod() + <::re_types_core::ArrowBuffer>::is_pod() + && >>::is_pod() && ::is_pod() } } diff --git a/crates/store/re_types/src/datatypes/tensor_data_ext.rs b/crates/store/re_types/src/datatypes/tensor_data_ext.rs index bca0ddde0c2d..537368d08ace 100644 --- a/crates/store/re_types/src/datatypes/tensor_data_ext.rs +++ b/crates/store/re_types/src/datatypes/tensor_data_ext.rs @@ -1,3 +1,5 @@ +use re_types_core::{ArrowBuffer, ArrowString}; + use crate::tensor_data::{TensorCastError, TensorDataType, TensorElement}; #[cfg(feature = "image")] @@ -6,33 +8,69 @@ use crate::tensor_data::TensorImageLoadError; #[allow(unused_imports)] // Used for docstring links use crate::archetypes::EncodedImage; -use super::{TensorBuffer, TensorData, TensorDimension}; +use super::{TensorBuffer, TensorData}; // ---------------------------------------------------------------------------- impl TensorData { /// Create a new tensor. #[inline] - pub fn new(shape: Vec, buffer: TensorBuffer) -> Self { - Self { shape, buffer } + pub fn new(shape: impl Into>, buffer: TensorBuffer) -> Self { + Self { + shape: shape.into(), + names: None, + buffer, + } } - /// The shape of the tensor, including optional dimension names. + /// Set the names of the dimensions to the provided names. + /// + /// Any existing names will be overwritten. + /// + /// If the wrong number of names are given, a warning will be logged, + /// and the names might not show up correctly. + pub fn with_dim_names( + mut self, + names: impl IntoIterator>, + ) -> Self { + let names: Vec = names.into_iter().map(|x| x.into()).collect(); + + if names.len() != self.shape.len() { + re_log::warn_once!( + "Wrong number of names provided for tensor dimension. {} provided but {} expected. The names will be ignored.", + names.len(), + self.shape.len(), + ); + } + + self.names = Some(names); + + self + } + + /// The shape of the tensor. #[inline] - pub fn shape(&self) -> &[TensorDimension] { + pub fn shape(&self) -> &[u64] { self.shape.as_slice() } + /// Get the name of a specific dimension. + /// + /// Returns `None` if the dimension does not have a name. + pub fn dim_name(&self, dim: usize) -> Option<&ArrowString> { + self.names.as_ref().and_then(|names| names.get(dim)) + } + /// Returns the shape of the tensor with all leading & trailing dimensions of size 1 ignored. /// /// If all dimension sizes are one, this returns only the first dimension. #[inline] - pub fn shape_short(&self) -> &[TensorDimension] { + pub fn shape_short(&self) -> &[u64] { if self.shape.is_empty() { &self.shape } else { - let first_not_one = self.shape.iter().position(|dim| dim.size != 1); - let last_not_one = self.shape.iter().rev().position(|dim| dim.size != 1); + let first_not_one = self.shape.iter().position(|&dim| dim != 1); + let last_not_one = self.shape.iter().rev().position(|&dim| dim != 1); &self.shape[first_not_one.unwrap_or(0)..self.shape.len() - last_not_one.unwrap_or(0)] } } @@ -53,7 +91,7 @@ impl TensorData { if self.shape.is_empty() { false } else { - self.shape.iter().filter(|dim| dim.size > 1).count() <= 1 + self.shape.iter().filter(|&&dim| dim > 1).count() <= 1 } } @@ -63,12 +101,12 @@ impl TensorData { pub fn get(&self, index: &[u64]) -> Option { let mut stride: usize = 1; let mut offset: usize = 0; - for (TensorDimension { size, .. }, index) in self.shape.iter().zip(index).rev() { + for (&size, &index) in self.shape.iter().zip(index).rev() { if size <= index { return None; } - offset += *index as usize * stride; - stride *= *size as usize; + offset += index as usize * stride; + stride *= size as usize; } match &self.buffer { @@ -103,7 +141,8 @@ impl Default for TensorData { #[inline] fn default() -> Self { Self { - shape: Vec::new(), + shape: Default::default(), + names: None, buffer: TensorBuffer::U8(Vec::new().into()), } } @@ -117,7 +156,7 @@ macro_rules! ndarray_from_tensor { type Error = TensorCastError; fn try_from(value: &'a TensorData) -> Result { - let shape: Vec<_> = value.shape.iter().map(|d| d.size as usize).collect(); + let shape: Vec = value.shape.iter().map(|&d| d as usize).collect(); if let TensorBuffer::$variant(data) = &value.buffer { ndarray::ArrayViewD::from_shape(shape, data.as_slice()) @@ -138,26 +177,17 @@ macro_rules! tensor_from_ndarray { type Error = TensorCastError; fn try_from(view: ::ndarray::ArrayView<'a, $type, D>) -> Result { - let shape = view - .shape() - .iter() - .map(|dim| TensorDimension { - size: *dim as u64, - name: None, - }) - .collect(); + let shape = ArrowBuffer::from_iter(view.shape().iter().map(|&dim| dim as u64)); match view.to_slice() { - Some(slice) => Ok(TensorData { + Some(slice) => Ok(TensorData::new( shape, - buffer: TensorBuffer::$variant(Vec::from(slice).into()), - }), - None => Ok(TensorData { + TensorBuffer::$variant(Vec::from(slice).into()), + )), + None => Ok(TensorData::new( shape, - buffer: TensorBuffer::$variant( - view.iter().cloned().collect::>().into(), - ), - }), + TensorBuffer::$variant(view.iter().cloned().collect::>().into()), + )), } } } @@ -166,14 +196,7 @@ macro_rules! tensor_from_ndarray { type Error = TensorCastError; fn try_from(value: ndarray::Array<$type, D>) -> Result { - let shape = value - .shape() - .iter() - .map(|dim| TensorDimension { - size: *dim as u64, - name: None, - }) - .collect(); + let shape = ArrowBuffer::from_iter(value.shape().iter().map(|&dim| dim as u64)); let vec = if value.is_standard_layout() { let (mut vec, offset) = value.into_raw_vec_and_offset(); @@ -190,28 +213,22 @@ macro_rules! tensor_from_ndarray { value.into_iter().collect::>() }; - Ok(Self { - shape, - buffer: TensorBuffer::$variant(vec.into()), - }) + Ok(Self::new(shape, TensorBuffer::$variant(vec.into()))) } } impl From> for TensorData { fn from(vec: Vec<$type>) -> Self { - TensorData { - shape: vec![TensorDimension::unnamed(vec.len() as u64)], - buffer: TensorBuffer::$variant(vec.into()), - } + Self::new(vec![vec.len() as u64], TensorBuffer::$variant(vec.into())) } } impl From<&[$type]> for TensorData { fn from(slice: &[$type]) -> Self { - TensorData { - shape: vec![TensorDimension::unnamed(slice.len() as u64)], - buffer: TensorBuffer::$variant(slice.into()), - } + Self::new( + vec![slice.len() as u64], + TensorBuffer::$variant(slice.into()), + ) } } }; @@ -247,7 +264,7 @@ impl<'a> TryFrom<&'a TensorData> for ::ndarray::ArrayViewD<'a, u8> { fn try_from(value: &'a TensorData) -> Result { match &value.buffer { TensorBuffer::U8(data) => { - let shape: Vec<_> = value.shape.iter().map(|d| d.size as usize).collect(); + let shape: Vec = value.shape.iter().map(|&d| d as usize).collect(); ndarray::ArrayViewD::from_shape(shape, bytemuck::cast_slice(data.as_slice())) .map_err(|err| TensorCastError::BadTensorShape { source: err }) } @@ -363,19 +380,15 @@ impl TensorData { )); } }; - let shape = if depth == 1 { - vec![ - TensorDimension::height(h as _), - TensorDimension::width(w as _), - ] + let (shape, names) = if depth == 1 { + (vec![h as _, w as _], vec!["height", "width"]) } else { - vec![ - TensorDimension::height(h as _), - TensorDimension::width(w as _), - TensorDimension::depth(depth), - ] + ( + vec![h as _, w as _, depth], + vec!["height", "width", "depth"], + ) }; - Ok(Self { shape, buffer }) + Ok(Self::new(shape, buffer).with_dim_names(names)) } } diff --git a/crates/store/re_types/src/datatypes/tensor_dimension.rs b/crates/store/re_types/src/datatypes/tensor_dimension.rs deleted file mode 100644 index 619c954eea2f..000000000000 --- a/crates/store/re_types/src/datatypes/tensor_dimension.rs +++ /dev/null @@ -1,266 +0,0 @@ -// DO NOT EDIT! This file was auto-generated by crates/build/re_types_builder/src/codegen/rust/api.rs -// Based on "crates/store/re_types/definitions/rerun/datatypes/tensor_dimension.fbs". - -#![allow(unused_imports)] -#![allow(unused_parens)] -#![allow(clippy::clone_on_copy)] -#![allow(clippy::cloned_instead_of_copied)] -#![allow(clippy::map_flatten)] -#![allow(clippy::needless_question_mark)] -#![allow(clippy::new_without_default)] -#![allow(clippy::redundant_closure)] -#![allow(clippy::too_many_arguments)] -#![allow(clippy::too_many_lines)] - -use ::re_types_core::external::arrow2; -use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; -use ::re_types_core::{ComponentDescriptor, ComponentName}; -use ::re_types_core::{DeserializationError, DeserializationResult}; - -/// **Datatype**: A single dimension within a multi-dimensional tensor. -#[derive(Clone, Default, Eq, PartialEq)] -pub struct TensorDimension { - /// The length of this dimension. - pub size: u64, - - /// The name of this dimension, e.g. "width", "height", "channel", "batch', …. - pub name: Option<::re_types_core::ArrowString>, -} - -::re_types_core::macros::impl_into_cow!(TensorDimension); - -impl ::re_types_core::Loggable for TensorDimension { - #[inline] - fn arrow_datatype() -> arrow::datatypes::DataType { - #![allow(clippy::wildcard_imports)] - use arrow::datatypes::*; - DataType::Struct(Fields::from(vec![ - Field::new("size", DataType::UInt64, false), - Field::new("name", DataType::Utf8, true), - ])) - } - - fn to_arrow_opt<'a>( - data: impl IntoIterator>>>, - ) -> SerializationResult - where - Self: Clone + 'a, - { - #![allow(clippy::wildcard_imports)] - #![allow(clippy::manual_is_variant_and)] - use ::re_types_core::{arrow_helpers::as_array_ref, Loggable as _, ResultExt as _}; - use arrow::{array::*, buffer::*, datatypes::*}; - Ok({ - let fields = Fields::from(vec![ - Field::new("size", DataType::UInt64, false), - Field::new("name", DataType::Utf8, true), - ]); - let (somes, data): (Vec<_>, Vec<_>) = data - .into_iter() - .map(|datum| { - let datum: Option<::std::borrow::Cow<'a, Self>> = datum.map(Into::into); - (datum.is_some(), datum) - }) - .unzip(); - let validity: Option = { - let any_nones = somes.iter().any(|some| !*some); - any_nones.then(|| somes.into()) - }; - as_array_ref(StructArray::new( - fields, - vec![ - { - let (somes, size): (Vec<_>, Vec<_>) = data - .iter() - .map(|datum| { - let datum = datum.as_ref().map(|datum| datum.size.clone()); - (datum.is_some(), datum) - }) - .unzip(); - let size_validity: Option = { - let any_nones = somes.iter().any(|some| !*some); - any_nones.then(|| somes.into()) - }; - as_array_ref(PrimitiveArray::::new( - ScalarBuffer::from( - size.into_iter() - .map(|v| v.unwrap_or_default()) - .collect::>(), - ), - size_validity, - )) - }, - { - let (somes, name): (Vec<_>, Vec<_>) = data - .iter() - .map(|datum| { - let datum = - datum.as_ref().map(|datum| datum.name.clone()).flatten(); - (datum.is_some(), datum) - }) - .unzip(); - let name_validity: Option = { - let any_nones = somes.iter().any(|some| !*some); - any_nones.then(|| somes.into()) - }; - { - let offsets = - arrow::buffer::OffsetBuffer::::from_lengths(name.iter().map( - |opt| opt.as_ref().map(|datum| datum.len()).unwrap_or_default(), - )); - let inner_data: arrow::buffer::Buffer = name - .into_iter() - .flatten() - .flat_map(|s| s.into_arrow2_buffer()) - .collect(); - #[allow(unsafe_code, clippy::undocumented_unsafe_blocks)] - as_array_ref(unsafe { - StringArray::new_unchecked(offsets, inner_data, name_validity) - }) - } - }, - ], - validity, - )) - }) - } - - fn from_arrow2_opt( - arrow_data: &dyn arrow2::array::Array, - ) -> DeserializationResult>> - where - Self: Sized, - { - #![allow(clippy::wildcard_imports)] - use ::re_types_core::{Loggable as _, ResultExt as _}; - use arrow::datatypes::*; - use arrow2::{array::*, buffer::*}; - Ok({ - let arrow_data = arrow_data - .as_any() - .downcast_ref::() - .ok_or_else(|| { - let expected = Self::arrow_datatype(); - let actual = arrow_data.data_type().clone(); - DeserializationError::datatype_mismatch(expected, actual) - }) - .with_context("rerun.datatypes.TensorDimension")?; - if arrow_data.is_empty() { - Vec::new() - } else { - let (arrow_data_fields, arrow_data_arrays) = - (arrow_data.fields(), arrow_data.values()); - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data_fields - .iter() - .map(|field| field.name.as_str()) - .zip(arrow_data_arrays) - .collect(); - let size = { - if !arrays_by_name.contains_key("size") { - return Err(DeserializationError::missing_struct_field( - Self::arrow_datatype(), - "size", - )) - .with_context("rerun.datatypes.TensorDimension"); - } - let arrow_data = &**arrays_by_name["size"]; - arrow_data - .as_any() - .downcast_ref::() - .ok_or_else(|| { - let expected = DataType::UInt64; - let actual = arrow_data.data_type().clone(); - DeserializationError::datatype_mismatch(expected, actual) - }) - .with_context("rerun.datatypes.TensorDimension#size")? - .into_iter() - .map(|opt| opt.copied()) - }; - let name = { - if !arrays_by_name.contains_key("name") { - return Err(DeserializationError::missing_struct_field( - Self::arrow_datatype(), - "name", - )) - .with_context("rerun.datatypes.TensorDimension"); - } - let arrow_data = &**arrays_by_name["name"]; - { - let arrow_data = arrow_data - .as_any() - .downcast_ref::>() - .ok_or_else(|| { - let expected = DataType::Utf8; - let actual = arrow_data.data_type().clone(); - DeserializationError::datatype_mismatch(expected, actual) - }) - .with_context("rerun.datatypes.TensorDimension#name")?; - let arrow_data_buf = arrow_data.values(); - let offsets = arrow_data.offsets(); - arrow2::bitmap::utils::ZipValidity::new_with_validity( - offsets.windows(2), - arrow_data.validity(), - ) - .map(|elem| { - elem.map(|window| { - let start = window[0] as usize; - let end = window[1] as usize; - let len = end - start; - if arrow_data_buf.len() < end { - return Err(DeserializationError::offset_slice_oob( - (start, end), - arrow_data_buf.len(), - )); - } - - #[allow(unsafe_code, clippy::undocumented_unsafe_blocks)] - let data = - unsafe { arrow_data_buf.clone().sliced_unchecked(start, len) }; - Ok(data) - }) - .transpose() - }) - .map(|res_or_opt| { - res_or_opt.map(|res_or_opt| { - res_or_opt.map(|v| ::re_types_core::ArrowString::from(v)) - }) - }) - .collect::>>>() - .with_context("rerun.datatypes.TensorDimension#name")? - .into_iter() - } - }; - arrow2::bitmap::utils::ZipValidity::new_with_validity( - ::itertools::izip!(size, name), - arrow_data.validity(), - ) - .map(|opt| { - opt.map(|(size, name)| { - Ok(Self { - size: size - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.datatypes.TensorDimension#size")?, - name, - }) - }) - .transpose() - }) - .collect::>>() - .with_context("rerun.datatypes.TensorDimension")? - } - }) - } -} - -impl ::re_types_core::SizeBytes for TensorDimension { - #[inline] - fn heap_size_bytes(&self) -> u64 { - self.size.heap_size_bytes() + self.name.heap_size_bytes() - } - - #[inline] - fn is_pod() -> bool { - ::is_pod() && >::is_pod() - } -} diff --git a/crates/store/re_types/src/datatypes/tensor_dimension_ext.rs b/crates/store/re_types/src/datatypes/tensor_dimension_ext.rs deleted file mode 100644 index 8f50ab11ecd9..000000000000 --- a/crates/store/re_types/src/datatypes/tensor_dimension_ext.rs +++ /dev/null @@ -1,60 +0,0 @@ -use super::TensorDimension; - -impl TensorDimension { - const DEFAULT_NAME_WIDTH: &'static str = "width"; - const DEFAULT_NAME_HEIGHT: &'static str = "height"; - const DEFAULT_NAME_DEPTH: &'static str = "depth"; - - /// Create a new dimension with a given size, and the name "height". - #[inline] - pub fn height(size: u64) -> Self { - Self::named(size, String::from(Self::DEFAULT_NAME_HEIGHT)) - } - - /// Create a new dimension with a given size, and the name "width". - #[inline] - pub fn width(size: u64) -> Self { - Self::named(size, String::from(Self::DEFAULT_NAME_WIDTH)) - } - - /// Create a new dimension with a given size, and the name "depth". - #[inline] - pub fn depth(size: u64) -> Self { - Self::named(size, String::from(Self::DEFAULT_NAME_DEPTH)) - } - - /// Create a named dimension. - #[inline] - pub fn named(size: u64, name: impl Into) -> Self { - Self { - size, - name: Some(name.into()), - } - } - - /// Create an unnamed dimension. - #[inline] - pub fn unnamed(size: u64) -> Self { - Self { size, name: None } - } -} - -impl std::fmt::Debug for TensorDimension { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - if let Some(name) = &self.name { - write!(f, "{}={}", name, self.size) - } else { - self.size.fmt(f) - } - } -} - -impl std::fmt::Display for TensorDimension { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - if let Some(name) = &self.name { - write!(f, "{}={}", name, self.size) - } else { - self.size.fmt(f) - } - } -} diff --git a/crates/store/re_types/src/image.rs b/crates/store/re_types/src/image.rs index 75e13f6f1e16..1041f07ff38b 100644 --- a/crates/store/re_types/src/image.rs +++ b/crates/store/re_types/src/image.rs @@ -1,10 +1,11 @@ //! Image-related utilities. +use re_types_core::ArrowBuffer; use smallvec::{smallvec, SmallVec}; use crate::{ datatypes::ChannelDatatype, - datatypes::{Blob, TensorBuffer, TensorData, TensorDimension}, + datatypes::{Blob, TensorBuffer, TensorData}, }; // ---------------------------------------------------------------------------- @@ -95,7 +96,7 @@ where /// The tensor did not have the right shape for an image (e.g. had too many dimensions). #[error("Could not create Image from TensorData with shape {0:?}")] - BadImageShape(Vec), + BadImageShape(ArrowBuffer), /// Happens if you try to cast `NV12` or `YUY2` to a depth image or segmentation image. #[error("Chroma downsampling is not supported for this image type (e.g. DepthImage or SegmentationImage)")] @@ -181,7 +182,7 @@ impl ImageChannelType for f64 { /// /// For instance: `[1, 480, 640, 3, 1]` would return `[1, 2, 3]`, /// the indices of the `[480, 640, 3]` dimensions. -pub fn find_non_empty_dim_indices(shape: &[TensorDimension]) -> SmallVec<[usize; 4]> { +pub fn find_non_empty_dim_indices(shape: &[u64]) -> SmallVec<[usize; 4]> { match shape.len() { 0 => return smallvec![], 1 => return smallvec![0], @@ -197,7 +198,7 @@ pub fn find_non_empty_dim_indices(shape: &[TensorDimension]) -> SmallVec<[usize; shape .iter() .enumerate() - .filter_map(|(ind, dim)| if dim.size != 1 { Some(ind) } else { None }); + .filter_map(|(ind, &dim)| if dim != 1 { Some(ind) } else { None }); // 0 is always a valid index. let mut min = non_unit_indices.next().unwrap_or(0); @@ -216,7 +217,7 @@ pub fn find_non_empty_dim_indices(shape: &[TensorDimension]) -> SmallVec<[usize; // Grow up to 3 if the inner dimension is already 3 or 4 (Color Images) // Otherwise, only grow up to 2. // (1x1x3) -> 1x1x3 rgb rather than 1x3 mono - let target_len = match shape[max].size { + let target_len = match shape[max] { 3 | 4 => 3, _ => 2, }; @@ -231,14 +232,7 @@ pub fn find_non_empty_dim_indices(shape: &[TensorDimension]) -> SmallVec<[usize; #[test] fn test_find_non_empty_dim_indices() { fn expect(shape: &[u64], expected: &[usize]) { - let dim: Vec<_> = shape - .iter() - .map(|s| TensorDimension { - size: *s, - name: None, - }) - .collect(); - let got = find_non_empty_dim_indices(&dim); + let got = find_non_empty_dim_indices(shape); assert!( got.as_slice() == expected, "Input: {shape:?}, got {got:?}, expected {expected:?}" diff --git a/crates/store/re_types/tests/types/tensor.rs b/crates/store/re_types/tests/types/tensor.rs index 3474ae7b1d35..2fb8a132217a 100644 --- a/crates/store/re_types/tests/types/tensor.rs +++ b/crates/store/re_types/tests/types/tensor.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use re_types::{ archetypes::Tensor, - datatypes::{TensorBuffer, TensorData, TensorDimension}, + datatypes::{TensorBuffer, TensorData}, tensor_data::TensorCastError, Archetype as _, AsComponents as _, }; @@ -12,20 +12,7 @@ use crate::util; #[test] fn tensor_roundtrip() { let all_expected = [Tensor { - data: TensorData { - shape: vec![ - TensorDimension { - size: 2, - name: None, - }, - TensorDimension { - size: 3, - name: None, - }, - ], - buffer: TensorBuffer::U8(vec![1, 2, 3, 4, 5, 6].into()), - } - .into(), + data: TensorData::new(vec![2, 3], TensorBuffer::U8(vec![1, 2, 3, 4, 5, 6].into())).into(), value_range: None, }]; @@ -60,14 +47,7 @@ fn tensor_roundtrip() { #[test] fn convert_tensor_to_ndarray_u8() { - let t = TensorData::new( - vec![ - TensorDimension::unnamed(3), - TensorDimension::unnamed(4), - TensorDimension::unnamed(5), - ], - TensorBuffer::U8(vec![0; 60].into()), - ); + let t = TensorData::new(vec![3, 4, 5], TensorBuffer::U8(vec![0; 60].into())); let n = ndarray::ArrayViewD::::try_from(&t).unwrap(); @@ -76,14 +56,7 @@ fn convert_tensor_to_ndarray_u8() { #[test] fn convert_tensor_to_ndarray_u16() { - let t = TensorData::new( - vec![ - TensorDimension::unnamed(3), - TensorDimension::unnamed(4), - TensorDimension::unnamed(5), - ], - TensorBuffer::U16(vec![0_u16; 60].into()), - ); + let t = TensorData::new(vec![3, 4, 5], TensorBuffer::U16(vec![0_u16; 60].into())); let n = ndarray::ArrayViewD::::try_from(&t).unwrap(); @@ -92,14 +65,7 @@ fn convert_tensor_to_ndarray_u16() { #[test] fn convert_tensor_to_ndarray_f32() { - let t = TensorData::new( - vec![ - TensorDimension::unnamed(3), - TensorDimension::unnamed(4), - TensorDimension::unnamed(5), - ], - TensorBuffer::F32(vec![0_f32; 60].into()), - ); + let t = TensorData::new(vec![3, 4, 5], TensorBuffer::F32(vec![0_f32; 60].into())); let n = ndarray::ArrayViewD::::try_from(&t).unwrap(); @@ -111,10 +77,7 @@ fn convert_ndarray_f64_to_tensor() { let n = ndarray::array![[1., 2., 3.], [4., 5., 6.]]; let t = TensorData::try_from(n).unwrap(); - assert_eq!( - t.shape(), - &[TensorDimension::unnamed(2), TensorDimension::unnamed(3)] - ); + assert_eq!(t.shape(), &[2, 3]); } #[test] @@ -123,7 +86,7 @@ fn convert_ndarray_slice_to_tensor() { let n = &n.slice(ndarray::s![.., 1]); let t = TensorData::try_from(*n).unwrap(); - assert_eq!(t.shape(), &[TensorDimension::unnamed(2)]); + assert_eq!(t.shape(), &[2]); } #[test] @@ -220,11 +183,7 @@ fn convert_ndarray_to_tensor_both_layouts_nonzero_offset() { #[test] fn check_slices() { let t = TensorData::new( - vec![ - TensorDimension::unnamed(3), - TensorDimension::unnamed(4), - TensorDimension::unnamed(5), - ], + vec![3, 4, 5], TensorBuffer::U16((0_u16..60).collect::>().into()), ); @@ -258,14 +217,7 @@ fn check_slices() { #[test] fn check_tensor_shape_error() { - let t = TensorData::new( - vec![ - TensorDimension::unnamed(3), - TensorDimension::unnamed(4), - TensorDimension::unnamed(5), - ], - TensorBuffer::U8(vec![0; 59].into()), - ); + let t = TensorData::new(vec![3, 4, 5], TensorBuffer::U8(vec![0; 59].into())); let n = ndarray::ArrayViewD::::try_from(&t); @@ -279,14 +231,7 @@ fn check_tensor_shape_error() { #[test] fn check_tensor_type_error() { - let t = TensorData::new( - vec![ - TensorDimension::unnamed(3), - TensorDimension::unnamed(4), - TensorDimension::unnamed(5), - ], - TensorBuffer::U16(vec![0; 60].into()), - ); + let t = TensorData::new(vec![3, 4, 5], TensorBuffer::U16(vec![0; 60].into())); let n = ndarray::ArrayViewD::::try_from(&t); diff --git a/crates/store/re_types_core/src/arrow_buffer.rs b/crates/store/re_types_core/src/arrow_buffer.rs index a8ed54e38d8d..a07e47ca2e88 100644 --- a/crates/store/re_types_core/src/arrow_buffer.rs +++ b/crates/store/re_types_core/src/arrow_buffer.rs @@ -133,6 +133,16 @@ impl FromIterator for ArrowBuffer { } } +impl<'a, T: ArrowNativeType> IntoIterator for &'a ArrowBuffer { + type Item = &'a T; + type IntoIter = std::slice::Iter<'a, T>; + + #[inline] + fn into_iter(self) -> Self::IntoIter { + self.as_slice().iter() + } +} + impl std::ops::Deref for ArrowBuffer { type Target = [T]; diff --git a/crates/top/rerun/src/commands/rrd/compare.rs b/crates/top/rerun/src/commands/rrd/compare.rs index 3472eacd8f90..c9c7c4778e4d 100644 --- a/crates/top/rerun/src/commands/rrd/compare.rs +++ b/crates/top/rerun/src/commands/rrd/compare.rs @@ -30,6 +30,8 @@ impl CompareCommand { full_dump, } = self; + re_log::debug!("Comparing {path_to_rrd1:?} to {path_to_rrd2:?}…"); + let path_to_rrd1 = PathBuf::from(path_to_rrd1); let path_to_rrd2 = PathBuf::from(path_to_rrd2); @@ -75,6 +77,8 @@ impl CompareCommand { ); } + re_log::debug!("{path_to_rrd1:?} and {path_to_rrd2:?} are similar enough."); + Ok(()) } } diff --git a/crates/top/rerun/src/lib.rs b/crates/top/rerun/src/lib.rs index c96f194d11a6..3386ccc73ddc 100644 --- a/crates/top/rerun/src/lib.rs +++ b/crates/top/rerun/src/lib.rs @@ -169,10 +169,10 @@ pub const EXTERNAL_DATA_LOADER_INCOMPATIBLE_EXIT_CODE: i32 = 66; pub mod external { pub use anyhow; - pub use re_build_info; - pub use re_entity_db; - pub use re_entity_db::external::*; - pub use re_format; + pub use ::re_build_info; + pub use ::re_entity_db; + pub use ::re_entity_db::external::*; + pub use ::re_format; #[cfg(feature = "run")] pub use re_data_source; diff --git a/crates/top/rerun/src/sdk.rs b/crates/top/rerun/src/sdk.rs index 4d8c70a28931..3eab417ce267 100644 --- a/crates/top/rerun/src/sdk.rs +++ b/crates/top/rerun/src/sdk.rs @@ -31,7 +31,7 @@ mod prelude { pub use re_types::datatypes::{ Angle, AnnotationInfo, ChannelDatatype, ClassDescription, ColorModel, Float32, KeypointPair, Mat3x3, PixelFormat, Quaternion, Rgba32, RotationAxisAngle, TensorBuffer, - TensorData, TensorDimension, Vec2D, Vec3D, Vec4D, + TensorData, Vec2D, Vec3D, Vec4D, }; } pub use prelude::*; diff --git a/crates/viewer/re_data_ui/src/tensor.rs b/crates/viewer/re_data_ui/src/tensor.rs index afe680f47228..badbb7f541b9 100644 --- a/crates/viewer/re_data_ui/src/tensor.rs +++ b/crates/viewer/re_data_ui/src/tensor.rs @@ -2,33 +2,38 @@ use itertools::Itertools as _; use re_chunk_store::RowId; use re_log_types::EntityPath; -use re_types::datatypes::{TensorData, TensorDimension}; +use re_types::datatypes::TensorData; use re_ui::UiExt as _; use re_viewer_context::{TensorStats, TensorStatsCache, UiLayout, ViewerContext}; use super::EntityDataUi; -pub fn format_tensor_shape_single_line(shape: &[TensorDimension]) -> String { +fn format_tensor_shape_single_line(tensor: &TensorData) -> String { const MAX_SHOWN: usize = 4; // should be enough for width/height/depth and then some! - let iter = shape.iter().take(MAX_SHOWN); - let labelled = iter.clone().any(|dim| dim.name.is_some()); - let shapes = iter - .map(|dim| { + let short_shape = &tensor.shape[0..tensor.shape.len().min(MAX_SHOWN)]; + let has_names = short_shape + .iter() + .enumerate() + .any(|(dim_idx, _)| tensor.dim_name(dim_idx).is_some()); + let shapes = short_shape + .iter() + .enumerate() + .map(|(dim_idx, dim_len)| { format!( "{}{}", - dim.size, - if let Some(name) = &dim.name { + dim_len, + if let Some(name) = tensor.dim_name(dim_idx) { format!(" ({name})") } else { String::new() } ) }) - .join(if labelled { " Γ— " } else { "Γ—" }); + .join(if has_names { " Γ— " } else { "Γ—" }); format!( "{shapes}{}", - if shape.len() > MAX_SHOWN { - if labelled { + if MAX_SHOWN < tensor.shape.len() { + if has_names { " Γ— …" } else { "×…" @@ -75,7 +80,7 @@ pub fn tensor_ui( let text = format!( "{}, {}", tensor.dtype(), - format_tensor_shape_single_line(&tensor.shape) + format_tensor_shape_single_line(tensor) ); ui_layout.label(ui, text).on_hover_ui(|ui| { tensor_summary_ui(ui, tensor, &tensor_stats); @@ -94,7 +99,7 @@ pub fn tensor_summary_ui_grid_contents( tensor: &TensorData, tensor_stats: &TensorStats, ) { - let TensorData { shape, buffer: _ } = tensor; + let TensorData { shape, names, .. } = tensor; ui.grid_left_hand_label("Data type") .on_hover_text("Data type used for all individual elements within the tensor"); @@ -107,12 +112,12 @@ pub fn tensor_summary_ui_grid_contents( // For unnamed tensor dimension more than a single line usually doesn't make sense! // But what if some are named and some are not? // -> If more than 1 is named, make it a column! - if shape.iter().filter(|d| d.name.is_some()).count() > 1 { - for dim in shape { - ui.label(dim.to_string()); + if let Some(names) = names { + for (name, size) in itertools::izip!(names, shape) { + ui.label(format!("{name}={size}")); } } else { - ui.label(format_tensor_shape_single_line(shape)); + ui.label(format_tensor_shape_single_line(tensor)); } }); ui.end_row(); diff --git a/crates/viewer/re_view_tensor/src/dimension_mapping.rs b/crates/viewer/re_view_tensor/src/dimension_mapping.rs index f3804733b1d8..43ccab9a812b 100644 --- a/crates/viewer/re_view_tensor/src/dimension_mapping.rs +++ b/crates/viewer/re_view_tensor/src/dimension_mapping.rs @@ -1,11 +1,14 @@ use egui::NumExt as _; + use re_types::{ blueprint::{archetypes::TensorSliceSelection, components::TensorDimensionIndexSlider}, components::{TensorDimensionIndexSelection, TensorHeightDimension, TensorWidthDimension}, - datatypes::{TensorDimension, TensorDimensionSelection}, + datatypes::TensorDimensionSelection, }; use re_viewport_blueprint::ViewProperty; +use crate::TensorDimension; + /// Loads slice selection from blueprint and makes modifications (without writing back) such that it is valid /// for the given tensor shape. /// @@ -250,7 +253,7 @@ fn longest_and_second_longest_dim_indices(shape: &[TensorDimension]) -> (usize, #[cfg(test)] mod tests { - use re_types::datatypes::TensorDimension; + use crate::TensorDimension; use re_types::{ blueprint::components::TensorDimensionIndexSlider, components::TensorDimensionIndexSelection, diff --git a/crates/viewer/re_view_tensor/src/lib.rs b/crates/viewer/re_view_tensor/src/lib.rs index 2dda9636b659..19492b29bf34 100644 --- a/crates/viewer/re_view_tensor/src/lib.rs +++ b/crates/viewer/re_view_tensor/src/lib.rs @@ -1,6 +1,6 @@ -//! Rerun tensor View. +//! Rerun tensor view. //! -//! A View dedicated to visualizing tensors with arbitrary dimensionality. +//! A view dedicated to visualizing tensors with arbitrary dimensionality. // TODO(#6330): remove unwrap() #![allow(clippy::unwrap_used)] @@ -12,3 +12,34 @@ mod view_class; mod visualizer_system; pub use view_class::TensorView; + +/// Information about a dimension of a tensor. +struct TensorDimension { + pub size: u64, + pub name: Option, +} + +impl TensorDimension { + pub fn from_tensor_data(tensor_data: &re_types::datatypes::TensorData) -> Vec { + tensor_data + .shape + .iter() + .enumerate() + .map(|(dim_idx, dim_len)| Self { + size: *dim_len, + name: tensor_data.dim_name(dim_idx).cloned(), + }) + .collect() + } + + pub fn unnamed(size: u64) -> Self { + Self { size, name: None } + } + + pub fn named(size: u64, name: impl Into) -> Self { + Self { + size, + name: Some(name.into()), + } + } +} diff --git a/crates/viewer/re_view_tensor/src/tensor_dimension_mapper.rs b/crates/viewer/re_view_tensor/src/tensor_dimension_mapper.rs index ac224320bc12..07e6bed75cb1 100644 --- a/crates/viewer/re_view_tensor/src/tensor_dimension_mapper.rs +++ b/crates/viewer/re_view_tensor/src/tensor_dimension_mapper.rs @@ -1,11 +1,12 @@ use re_types::{ - blueprint::archetypes::TensorSliceSelection, - datatypes::{TensorDimension, TensorDimensionIndexSelection}, + blueprint::archetypes::TensorSliceSelection, datatypes::TensorDimensionIndexSelection, }; use re_ui::UiExt as _; use re_viewer_context::ViewerContext; use re_viewport_blueprint::ViewProperty; +use crate::TensorDimension; + #[derive(Clone, Copy, PartialEq, Eq)] enum DragDropAddress { None, diff --git a/crates/viewer/re_view_tensor/src/tensor_tests.rs b/crates/viewer/re_view_tensor/src/tensor_tests.rs index e8e46712330e..0da7b00c5394 100644 --- a/crates/viewer/re_view_tensor/src/tensor_tests.rs +++ b/crates/viewer/re_view_tensor/src/tensor_tests.rs @@ -1,6 +1,6 @@ #![allow(clippy::unwrap_used)] -use re_types::datatypes::{TensorBuffer, TensorData, TensorDimension}; +use re_types::datatypes::{TensorBuffer, TensorData}; use re_types::tensor_data::TensorCastError; #[test] diff --git a/crates/viewer/re_view_tensor/src/view_class.rs b/crates/viewer/re_view_tensor/src/view_class.rs index 191c327de4fe..0e8165f0101a 100644 --- a/crates/viewer/re_view_tensor/src/view_class.rs +++ b/crates/viewer/re_view_tensor/src/view_class.rs @@ -1,6 +1,5 @@ use egui::{epaint::TextShape, Align2, NumExt as _, Vec2}; use ndarray::Axis; -use re_view::{suggest_view_for_each_entity, view_property_ui}; use re_data_ui::tensor_summary_ui_grid_contents; use re_log_types::EntityPath; @@ -10,10 +9,11 @@ use re_types::{ components::ViewFit, }, components::{Colormap, GammaCorrection, MagnificationFilter, TensorDimensionIndexSelection}, - datatypes::{TensorData, TensorDimension}, + datatypes::TensorData, View, ViewClassIdentifier, }; use re_ui::{list_item, UiExt as _}; +use re_view::{suggest_view_for_each_entity, view_property_ui}; use re_viewer_context::{ gpu_bridge, ApplicableEntities, ColormapWithRange, IdentifiedViewSystem as _, IndicatedEntities, PerVisualizer, TensorStatsCache, TypedComponentFallbackProvider, ViewClass, @@ -26,6 +26,7 @@ use crate::{ dimension_mapping::load_tensor_slice_selection_and_make_valid, tensor_dimension_mapper::dimension_mapping_ui, visualizer_system::{TensorSystem, TensorVisualization}, + TensorDimension, }; #[derive(Default)] @@ -151,12 +152,20 @@ Note: select the view to configure which dimensions are shown." ctx.blueprint_query, view_id, ); - let slice_selection = - load_tensor_slice_selection_and_make_valid(&slice_property, tensor.shape())?; + let slice_selection = load_tensor_slice_selection_and_make_valid( + &slice_property, + &TensorDimension::from_tensor_data(tensor), + )?; ui.separator(); ui.strong("Dimension Mapping"); - dimension_mapping_ui(ctx, ui, tensor.shape(), &slice_selection, &slice_property); + dimension_mapping_ui( + ctx, + ui, + &TensorDimension::from_tensor_data(tensor), + &slice_selection, + &slice_property, + ); // TODO(andreas): this is a bit too inconsistent with the other UIs - we don't offer the same reset/option buttons here if ui @@ -242,8 +251,10 @@ impl TensorView { ctx.blueprint_query, view_id, ); - let slice_selection = - load_tensor_slice_selection_and_make_valid(&slice_property, tensor.shape())?; + let slice_selection = load_tensor_slice_selection_and_make_valid( + &slice_property, + &TensorDimension::from_tensor_data(tensor), + )?; let default_item_spacing = ui.spacing_mut().item_spacing; ui.spacing_mut().item_spacing.y = 0.0; // No extra spacing between sliders and tensor @@ -259,17 +270,26 @@ impl TensorView { } .show(ui, |ui| { ui.spacing_mut().item_spacing = default_item_spacing; // keep the default spacing between sliders - selectors_ui(ctx, ui, tensor.shape(), &slice_selection, &slice_property); + selectors_ui( + ctx, + ui, + &TensorDimension::from_tensor_data(tensor), + &slice_selection, + &slice_property, + ); }); } let dimension_labels = [ - slice_selection - .width - .map(|width| (dimension_name(&tensor.shape, width.dimension), width.invert)), + slice_selection.width.map(|width| { + ( + dimension_name(&TensorDimension::from_tensor_data(tensor), width.dimension), + width.invert, + ) + }), slice_selection.height.map(|height| { ( - dimension_name(&tensor.shape, height.dimension), + dimension_name(&TensorDimension::from_tensor_data(tensor), height.dimension), height.invert, ) }), diff --git a/docs/content/reference/migration/migration-0-21.md b/docs/content/reference/migration/migration-0-21.md index 15c149d369f1..84a720a41338 100644 --- a/docs/content/reference/migration/migration-0-21.md +++ b/docs/content/reference/migration/migration-0-21.md @@ -3,6 +3,9 @@ title: Migrating from 0.20 to 0.21 order: 989 --- +### File compatibility +We've changed how tensors are encoded in .rrd files, so tensors will no longer load from older .rrd files ([#8376](https://github.com/rerun-io/rerun/pull/8376)). + ### Near clip plane for `Spatial2D` views now defaults to `0.1` in 3D scene units. Previously, the clip plane was set an arbitrary value that worked reasonably for diff --git a/docs/content/reference/types/components/tensor_data.md b/docs/content/reference/types/components/tensor_data.md index 212c6f45a755..3de2724c3242 100644 --- a/docs/content/reference/types/components/tensor_data.md +++ b/docs/content/reference/types/components/tensor_data.md @@ -19,10 +19,8 @@ which stores a contiguous array of typed values. ## Arrow datatype ``` Struct { - shape: List + shape: List + names: nullable List buffer: DenseUnion { 0 = "_null_markers": nullable null 1 = "U8": List diff --git a/docs/content/reference/types/datatypes.md b/docs/content/reference/types/datatypes.md index 6902ee39e313..b12bd42d39db 100644 --- a/docs/content/reference/types/datatypes.md +++ b/docs/content/reference/types/datatypes.md @@ -34,7 +34,6 @@ Data types are the lowest layer of the data model hierarchy. They are re-usable * [`RotationAxisAngle`](datatypes/rotation_axis_angle.md): 3D rotation represented by a rotation around a given axis. * [`TensorBuffer`](datatypes/tensor_buffer.md): The underlying storage for [`archetypes.Tensor`](https://rerun.io/docs/reference/types/archetypes/tensor). * [`TensorData`](datatypes/tensor_data.md): An N-dimensional array of numbers. -* [`TensorDimension`](datatypes/tensor_dimension.md): A single dimension within a multi-dimensional tensor. * [`TensorDimensionIndexSelection`](datatypes/tensor_dimension_index_selection.md): Indexing a specific tensor dimension. * [`TensorDimensionSelection`](datatypes/tensor_dimension_selection.md): Selection of a single tensor dimension. * [`TimeInt`](datatypes/time_int.md): A 64-bit number describing either nanoseconds OR sequence numbers. diff --git a/docs/content/reference/types/datatypes/.gitattributes b/docs/content/reference/types/datatypes/.gitattributes index 3454eebe12d8..771fe1303bcf 100644 --- a/docs/content/reference/types/datatypes/.gitattributes +++ b/docs/content/reference/types/datatypes/.gitattributes @@ -28,7 +28,6 @@ rgba32.md linguist-generated=true rotation_axis_angle.md linguist-generated=true tensor_buffer.md linguist-generated=true tensor_data.md linguist-generated=true -tensor_dimension.md linguist-generated=true tensor_dimension_index_selection.md linguist-generated=true tensor_dimension_selection.md linguist-generated=true time_int.md linguist-generated=true diff --git a/docs/content/reference/types/datatypes/tensor_data.md b/docs/content/reference/types/datatypes/tensor_data.md index d8af8ecbb674..abc09ba17823 100644 --- a/docs/content/reference/types/datatypes/tensor_data.md +++ b/docs/content/reference/types/datatypes/tensor_data.md @@ -14,9 +14,20 @@ which stores a contiguous array of typed values. ## Fields #### `shape` -Type: List of [`TensorDimension`](../datatypes/tensor_dimension.md) +Type: List of `uint64` -The shape of the tensor, including optional names for each dimension. +The shape of the tensor, i.e. the length of each dimension. + +#### `names` +Type: nullable List of `utf8` + +The names of the dimensions of the tensor (optional). + +If set, should be the same length as [`datatypes.TensorData#shape`](https://rerun.io/docs/reference/types/datatypes/tensor_data). +If it has a different length your names may show up improperly, +and some constructors may produce a warning or even an error. + +Example: `["height", "width", "channel", "batch"]`. #### `buffer` Type: [`TensorBuffer`](../datatypes/tensor_buffer.md) @@ -27,10 +38,8 @@ The content/data. ## Arrow datatype ``` Struct { - shape: List + shape: List + names: nullable List buffer: DenseUnion { 0 = "_null_markers": nullable null 1 = "U8": List diff --git a/docs/content/reference/types/datatypes/tensor_dimension.md b/docs/content/reference/types/datatypes/tensor_dimension.md deleted file mode 100644 index 71d1446ed11e..000000000000 --- a/docs/content/reference/types/datatypes/tensor_dimension.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -title: "TensorDimension" ---- - - -A single dimension within a multi-dimensional tensor. - -## Fields -#### `size` -Type: `uint64` - -The length of this dimension. - -#### `name` -Type: nullable `utf8` - -The name of this dimension, e.g. "width", "height", "channel", "batch', …. - - -## Arrow datatype -``` -Struct { - size: uint64 - name: nullable utf8 -} -``` - -## API reference links - * 🌊 [C++ API docs for `TensorDimension`](https://ref.rerun.io/docs/cpp/stable/structrerun_1_1datatypes_1_1TensorDimension.html) - * 🐍 [Python API docs for `TensorDimension`](https://ref.rerun.io/docs/python/stable/common/datatypes#rerun.datatypes.TensorDimension) - * πŸ¦€ [Rust API docs for `TensorDimension`](https://docs.rs/rerun/latest/rerun/datatypes/struct.TensorDimension.html) - - -## Used by - -* [`TensorData`](../datatypes/tensor_data.md) diff --git a/docs/snippets/README.md b/docs/snippets/README.md index a221615ae85a..21d51dcb2c10 100644 --- a/docs/snippets/README.md +++ b/docs/snippets/README.md @@ -11,7 +11,7 @@ You can run each example individually using the following: - **C++**: - `pixi run -e cpp cpp-build-snippets` to compile all examples - `./build/debug/docs/snippets/all/` to run, e.g. `./build/debug/docs/snippets/all/point3d_random` -- **Python**: `pixi run -e py python .py`, e.g. `pixi run -e py python point3d_random.py`. +- **Python**: `pixi run py-build && pixi run -e py python .py`, e.g. `pixi run -e py python point3d_random.py`. - **Rust**: `cargo run -p snippets -- [args]`, e.g. `cargo run -p snippets -- point3d_random`. ## Comparison test @@ -23,8 +23,8 @@ These tests check that A) all of our SDKs yield the exact same data when used th ### Usage -To run the comparison tests, check out `./docs/snippets/compare_snippet_output.py --help`. -`./docs/snippets/compare_snippet_output.py` is a valid invocation that will build all 3 SDKs and run all tests for all of them. +To run the comparison tests, check out `pixi run -e py docs/snippets/compare_snippet_output.py --help`. +`pixi run -e py docs/snippets/compare_snippet_output.py` is a valid invocation that will build all 3 SDKs and run all tests for all of them. ### Implementing new tests diff --git a/rerun_cpp/src/rerun.hpp b/rerun_cpp/src/rerun.hpp index 8f4546fc4c01..4b2d4933db05 100644 --- a/rerun_cpp/src/rerun.hpp +++ b/rerun_cpp/src/rerun.hpp @@ -66,7 +66,6 @@ namespace rerun { using datatypes::RotationAxisAngle; using datatypes::TensorBuffer; using datatypes::TensorData; - using datatypes::TensorDimension; using datatypes::Vec2D; using datatypes::Vec3D; using datatypes::Vec4D; diff --git a/rerun_cpp/src/rerun/archetypes/tensor.hpp b/rerun_cpp/src/rerun/archetypes/tensor.hpp index 881c6f34bb60..8f2b553ab2c9 100644 --- a/rerun_cpp/src/rerun/archetypes/tensor.hpp +++ b/rerun_cpp/src/rerun/archetypes/tensor.hpp @@ -77,7 +77,7 @@ namespace rerun::archetypes { public: // START of extensions from tensor_ext.cpp: /// New Tensor from dimensions and tensor buffer. - Tensor(Collection shape, datatypes::TensorBuffer buffer) + Tensor(Collection shape, datatypes::TensorBuffer buffer) : Tensor(datatypes::TensorData(std::move(shape), std::move(buffer))) {} /// New tensor from dimensions and pointer to tensor data. @@ -88,7 +88,7 @@ namespace rerun::archetypes { /// \param data_ /// Target of the pointer must outlive the archetype. template - explicit Tensor(Collection shape, const TElement* data_) + explicit Tensor(Collection shape, const TElement* data_) : Tensor(datatypes::TensorData(std::move(shape), data_)) {} /// Update the `names` of the contained `TensorData` dimensions. diff --git a/rerun_cpp/src/rerun/archetypes/tensor_ext.cpp b/rerun_cpp/src/rerun/archetypes/tensor_ext.cpp index 850416c0bed9..d684252c1822 100644 --- a/rerun_cpp/src/rerun/archetypes/tensor_ext.cpp +++ b/rerun_cpp/src/rerun/archetypes/tensor_ext.cpp @@ -13,7 +13,7 @@ namespace rerun::archetypes { // /// New Tensor from dimensions and tensor buffer. - Tensor(Collection shape, datatypes::TensorBuffer buffer) + Tensor(Collection shape, datatypes::TensorBuffer buffer) : Tensor(datatypes::TensorData(std::move(shape), std::move(buffer))) {} /// New tensor from dimensions and pointer to tensor data. @@ -24,7 +24,7 @@ namespace rerun::archetypes { /// \param data_ /// Target of the pointer must outlive the archetype. template - explicit Tensor(Collection shape, const TElement* data_) + explicit Tensor(Collection shape, const TElement* data_) : Tensor(datatypes::TensorData(std::move(shape), data_)) {} /// Update the `names` of the contained `TensorData` dimensions. @@ -51,11 +51,7 @@ namespace rerun::archetypes { .handle(); } - auto new_shape = shape.to_vector(); - for (size_t i = 0; i < std::min(shape.size(), names.size()); ++i) { - new_shape[i].name = std::move(names[i]); - } - shape = std::move(new_shape); + this->data.data.names = std::move(names); return std::move(*this); } diff --git a/rerun_cpp/src/rerun/components/tensor_data.hpp b/rerun_cpp/src/rerun/components/tensor_data.hpp index d85bb7960091..a7ececf996fd 100644 --- a/rerun_cpp/src/rerun/components/tensor_data.hpp +++ b/rerun_cpp/src/rerun/components/tensor_data.hpp @@ -28,10 +28,7 @@ namespace rerun::components { /// /// \param shape Shape of the tensor. /// \param buffer The tensor buffer containing the tensor's data. - TensorData( - rerun::Collection shape, - rerun::datatypes::TensorBuffer buffer - ) + TensorData(rerun::Collection shape, rerun::datatypes::TensorBuffer buffer) : data(rerun::datatypes::TensorData(std::move(shape), std::move(buffer))) {} /// New tensor data from dimensions and pointer to tensor data. @@ -40,7 +37,7 @@ namespace rerun::components { /// \param shape Shape of the tensor. Determines the number of elements expected to be in `data_`. /// \param data_ Target of the pointer must outlive the archetype. template - explicit TensorData(Collection shape, const TElement* data_) + explicit TensorData(Collection shape, const TElement* data_) : data(rerun::datatypes::TensorData(std::move(shape), data_)) {} // END of extensions from tensor_data_ext.cpp, start of generated code: diff --git a/rerun_cpp/src/rerun/components/tensor_data_ext.cpp b/rerun_cpp/src/rerun/components/tensor_data_ext.cpp index 3da2dde1f4cf..3d797a51f227 100644 --- a/rerun_cpp/src/rerun/components/tensor_data_ext.cpp +++ b/rerun_cpp/src/rerun/components/tensor_data_ext.cpp @@ -11,7 +11,7 @@ namespace rerun::components { /// \param shape Shape of the tensor. /// \param buffer The tensor buffer containing the tensor's data. TensorData( - rerun::Collection shape, + rerun::Collection shape, rerun::datatypes::TensorBuffer buffer ) : data(rerun::datatypes::TensorData(std::move(shape), std::move(buffer))) {} @@ -22,7 +22,7 @@ namespace rerun::components { /// \param shape Shape of the tensor. Determines the number of elements expected to be in `data_`. /// \param data_ Target of the pointer must outlive the archetype. template - explicit TensorData(Collection shape, const TElement* data_) + explicit TensorData(Collection shape, const TElement* data_) : data(rerun::datatypes::TensorData(std::move(shape), data_)) {} // diff --git a/rerun_cpp/src/rerun/datatypes.hpp b/rerun_cpp/src/rerun/datatypes.hpp index 0d41f3d62a23..30807019b8a6 100644 --- a/rerun_cpp/src/rerun/datatypes.hpp +++ b/rerun_cpp/src/rerun/datatypes.hpp @@ -29,7 +29,6 @@ #include "datatypes/rotation_axis_angle.hpp" #include "datatypes/tensor_buffer.hpp" #include "datatypes/tensor_data.hpp" -#include "datatypes/tensor_dimension.hpp" #include "datatypes/tensor_dimension_index_selection.hpp" #include "datatypes/tensor_dimension_selection.hpp" #include "datatypes/time_int.hpp" diff --git a/rerun_cpp/src/rerun/datatypes/.gitattributes b/rerun_cpp/src/rerun/datatypes/.gitattributes index 46c43435cc8b..a571592c1e65 100644 --- a/rerun_cpp/src/rerun/datatypes/.gitattributes +++ b/rerun_cpp/src/rerun/datatypes/.gitattributes @@ -55,8 +55,6 @@ tensor_buffer.cpp linguist-generated=true tensor_buffer.hpp linguist-generated=true tensor_data.cpp linguist-generated=true tensor_data.hpp linguist-generated=true -tensor_dimension.cpp linguist-generated=true -tensor_dimension.hpp linguist-generated=true tensor_dimension_index_selection.cpp linguist-generated=true tensor_dimension_index_selection.hpp linguist-generated=true tensor_dimension_selection.cpp linguist-generated=true diff --git a/rerun_cpp/src/rerun/datatypes/tensor_data.cpp b/rerun_cpp/src/rerun/datatypes/tensor_data.cpp index dfaa17f489c0..0a53b1bec03d 100644 --- a/rerun_cpp/src/rerun/datatypes/tensor_data.cpp +++ b/rerun_cpp/src/rerun/datatypes/tensor_data.cpp @@ -4,7 +4,6 @@ #include "tensor_data.hpp" #include "tensor_buffer.hpp" -#include "tensor_dimension.hpp" #include #include @@ -14,15 +13,8 @@ namespace rerun::datatypes {} namespace rerun { const std::shared_ptr& Loggable::arrow_datatype() { static const auto datatype = arrow::struct_({ - arrow::field( - "shape", - arrow::list(arrow::field( - "item", - Loggable::arrow_datatype(), - false - )), - false - ), + arrow::field("shape", arrow::list(arrow::field("item", arrow::uint64(), false)), false), + arrow::field("names", arrow::list(arrow::field("item", arrow::utf8(), false)), true), arrow::field( "buffer", Loggable::arrow_datatype(), @@ -67,26 +59,41 @@ namespace rerun { { auto field_builder = static_cast(builder->field_builder(0)); - auto value_builder = static_cast(field_builder->value_builder()); + auto value_builder = static_cast(field_builder->value_builder()); ARROW_RETURN_NOT_OK(field_builder->Reserve(static_cast(num_elements))); ARROW_RETURN_NOT_OK(value_builder->Reserve(static_cast(num_elements * 2))); for (size_t elem_idx = 0; elem_idx < num_elements; elem_idx += 1) { const auto& element = elements[elem_idx]; ARROW_RETURN_NOT_OK(field_builder->Append()); - if (element.shape.data()) { - RR_RETURN_NOT_OK( - Loggable::fill_arrow_array_builder( - value_builder, - element.shape.data(), - element.shape.size() - ) - ); + ARROW_RETURN_NOT_OK(value_builder->AppendValues( + element.shape.data(), + static_cast(element.shape.size()), + nullptr + )); + } + } + { + auto field_builder = static_cast(builder->field_builder(1)); + auto value_builder = static_cast(field_builder->value_builder()); + ARROW_RETURN_NOT_OK(field_builder->Reserve(static_cast(num_elements))); + ARROW_RETURN_NOT_OK(value_builder->Reserve(static_cast(num_elements * 1))); + + for (size_t elem_idx = 0; elem_idx < num_elements; elem_idx += 1) { + const auto& element = elements[elem_idx]; + if (element.names.has_value()) { + ARROW_RETURN_NOT_OK(field_builder->Append()); + for (size_t item_idx = 0; item_idx < element.names.value().size(); + item_idx += 1) { + ARROW_RETURN_NOT_OK(value_builder->Append(element.names.value()[item_idx])); + } + } else { + ARROW_RETURN_NOT_OK(field_builder->AppendNull()); } } } { - auto field_builder = static_cast(builder->field_builder(1)); + auto field_builder = static_cast(builder->field_builder(2)); ARROW_RETURN_NOT_OK(field_builder->Reserve(static_cast(num_elements))); for (size_t elem_idx = 0; elem_idx < num_elements; elem_idx += 1) { RR_RETURN_NOT_OK(Loggable::fill_arrow_array_builder( diff --git a/rerun_cpp/src/rerun/datatypes/tensor_data.hpp b/rerun_cpp/src/rerun/datatypes/tensor_data.hpp index b09aae93f06b..5822b81be239 100644 --- a/rerun_cpp/src/rerun/datatypes/tensor_data.hpp +++ b/rerun_cpp/src/rerun/datatypes/tensor_data.hpp @@ -7,10 +7,11 @@ #include "../component_descriptor.hpp" #include "../result.hpp" #include "tensor_buffer.hpp" -#include "tensor_dimension.hpp" #include #include +#include +#include namespace arrow { class Array; @@ -28,8 +29,17 @@ namespace rerun::datatypes { /// These dimensions are combined with an index to look up values from the `buffer` field, /// which stores a contiguous array of typed values. struct TensorData { - /// The shape of the tensor, including optional names for each dimension. - rerun::Collection shape; + /// The shape of the tensor, i.e. the length of each dimension. + rerun::Collection shape; + + /// The names of the dimensions of the tensor (optional). + /// + /// If set, should be the same length as `datatypes::TensorData::shape`. + /// If it has a different length your names may show up improperly, + /// and some constructors may produce a warning or even an error. + /// + /// Example: `["height", "width", "channel", "batch"]`. + std::optional> names; /// The content/data. rerun::datatypes::TensorBuffer buffer; @@ -39,9 +49,7 @@ namespace rerun::datatypes { /// /// \param shape_ Shape of the tensor. /// \param buffer_ The tensor buffer containing the tensor's data. - TensorData( - Collection shape_, datatypes::TensorBuffer buffer_ - ) + TensorData(Collection shape_, datatypes::TensorBuffer buffer_) : shape(std::move(shape_)), buffer(std::move(buffer_)) {} /// New tensor data from dimensions and pointer to tensor data. @@ -50,11 +58,11 @@ namespace rerun::datatypes { /// \param shape_ Shape of the tensor. Determines the number of elements expected to be in `data`. /// \param data Target of the pointer must outlive the archetype. template - explicit TensorData(Collection shape_, const TElement* data) + explicit TensorData(Collection shape_, const TElement* data) : shape(std::move(shape_)) { size_t num_elements = shape.empty() ? 0 : 1; for (const auto& dim : shape) { - num_elements *= dim.size; + num_elements *= dim; } buffer = rerun::Collection::borrow(data, num_elements); } diff --git a/rerun_cpp/src/rerun/datatypes/tensor_data_ext.cpp b/rerun_cpp/src/rerun/datatypes/tensor_data_ext.cpp index 2c0aa306117b..a7a6c0fda766 100644 --- a/rerun_cpp/src/rerun/datatypes/tensor_data_ext.cpp +++ b/rerun_cpp/src/rerun/datatypes/tensor_data_ext.cpp @@ -10,7 +10,7 @@ namespace rerun::datatypes { /// \param shape_ Shape of the tensor. /// \param buffer_ The tensor buffer containing the tensor's data. TensorData( - Collection shape_, datatypes::TensorBuffer buffer_ + Collection shape_, datatypes::TensorBuffer buffer_ ) : shape(std::move(shape_)), buffer(std::move(buffer_)) {} @@ -20,10 +20,10 @@ namespace rerun::datatypes { /// \param shape_ Shape of the tensor. Determines the number of elements expected to be in `data`. /// \param data Target of the pointer must outlive the archetype. template - explicit TensorData(Collection shape_, const TElement* data) : shape(std::move(shape_)) { + explicit TensorData(Collection shape_, const TElement* data) : shape(std::move(shape_)) { size_t num_elements = shape.empty() ? 0 : 1; for (const auto& dim : shape) { - num_elements *= dim.size; + num_elements *= dim; } buffer = rerun::Collection::borrow(data, num_elements); } diff --git a/rerun_cpp/src/rerun/datatypes/tensor_dimension.cpp b/rerun_cpp/src/rerun/datatypes/tensor_dimension.cpp deleted file mode 100644 index c58c45b1264a..000000000000 --- a/rerun_cpp/src/rerun/datatypes/tensor_dimension.cpp +++ /dev/null @@ -1,77 +0,0 @@ -// DO NOT EDIT! This file was auto-generated by crates/build/re_types_builder/src/codegen/cpp/mod.rs -// Based on "crates/store/re_types/definitions/rerun/datatypes/tensor_dimension.fbs". - -#include "tensor_dimension.hpp" - -#include -#include - -namespace rerun::datatypes {} - -namespace rerun { - const std::shared_ptr& Loggable::arrow_datatype() { - static const auto datatype = arrow::struct_({ - arrow::field("size", arrow::uint64(), false), - arrow::field("name", arrow::utf8(), true), - }); - return datatype; - } - - Result> Loggable::to_arrow( - const datatypes::TensorDimension* instances, size_t num_instances - ) { - // TODO(andreas): Allow configuring the memory pool. - arrow::MemoryPool* pool = arrow::default_memory_pool(); - auto datatype = arrow_datatype(); - - ARROW_ASSIGN_OR_RAISE(auto builder, arrow::MakeBuilder(datatype, pool)) - if (instances && num_instances > 0) { - RR_RETURN_NOT_OK(Loggable::fill_arrow_array_builder( - static_cast(builder.get()), - instances, - num_instances - )); - } - std::shared_ptr array; - ARROW_RETURN_NOT_OK(builder->Finish(&array)); - return array; - } - - rerun::Error Loggable::fill_arrow_array_builder( - arrow::StructBuilder* builder, const datatypes::TensorDimension* elements, - size_t num_elements - ) { - if (builder == nullptr) { - return rerun::Error(ErrorCode::UnexpectedNullArgument, "Passed array builder is null."); - } - if (elements == nullptr) { - return rerun::Error( - ErrorCode::UnexpectedNullArgument, - "Cannot serialize null pointer to arrow array." - ); - } - - { - auto field_builder = static_cast(builder->field_builder(0)); - ARROW_RETURN_NOT_OK(field_builder->Reserve(static_cast(num_elements))); - for (size_t elem_idx = 0; elem_idx < num_elements; elem_idx += 1) { - ARROW_RETURN_NOT_OK(field_builder->Append(elements[elem_idx].size)); - } - } - { - auto field_builder = static_cast(builder->field_builder(1)); - ARROW_RETURN_NOT_OK(field_builder->Reserve(static_cast(num_elements))); - for (size_t elem_idx = 0; elem_idx < num_elements; elem_idx += 1) { - const auto& element = elements[elem_idx]; - if (element.name.has_value()) { - ARROW_RETURN_NOT_OK(field_builder->Append(element.name.value())); - } else { - ARROW_RETURN_NOT_OK(field_builder->AppendNull()); - } - } - } - ARROW_RETURN_NOT_OK(builder->AppendValues(static_cast(num_elements), nullptr)); - - return Error::ok(); - } -} // namespace rerun diff --git a/rerun_cpp/src/rerun/datatypes/tensor_dimension.hpp b/rerun_cpp/src/rerun/datatypes/tensor_dimension.hpp deleted file mode 100644 index 052ff23efffd..000000000000 --- a/rerun_cpp/src/rerun/datatypes/tensor_dimension.hpp +++ /dev/null @@ -1,66 +0,0 @@ -// DO NOT EDIT! This file was auto-generated by crates/build/re_types_builder/src/codegen/cpp/mod.rs -// Based on "crates/store/re_types/definitions/rerun/datatypes/tensor_dimension.fbs". - -#pragma once - -#include "../component_descriptor.hpp" -#include "../result.hpp" - -#include -#include -#include -#include - -namespace arrow { - class Array; - class DataType; - class StructBuilder; -} // namespace arrow - -namespace rerun::datatypes { - /// **Datatype**: A single dimension within a multi-dimensional tensor. - struct TensorDimension { - /// The length of this dimension. - uint64_t size; - - /// The name of this dimension, e.g. "width", "height", "channel", "batch', …. - std::optional name; - - public: // START of extensions from tensor_dimension_ext.cpp: - /// Nameless dimension. - TensorDimension(size_t size_) : size(size_) {} - - /// Dimension with name. - TensorDimension(size_t size_, std::string name_) : size(size_), name(std::move(name_)) {} - - // END of extensions from tensor_dimension_ext.cpp, start of generated code: - - public: - TensorDimension() = default; - }; -} // namespace rerun::datatypes - -namespace rerun { - template - struct Loggable; - - /// \private - template <> - struct Loggable { - static constexpr ComponentDescriptor Descriptor = "rerun.datatypes.TensorDimension"; - - /// Returns the arrow data type this type corresponds to. - static const std::shared_ptr& arrow_datatype(); - - /// Serializes an array of `rerun::datatypes::TensorDimension` into an arrow array. - static Result> to_arrow( - const datatypes::TensorDimension* instances, size_t num_instances - ); - - /// Fills an arrow array builder with an array of this type. - static rerun::Error fill_arrow_array_builder( - arrow::StructBuilder* builder, const datatypes::TensorDimension* elements, - size_t num_elements - ); - }; -} // namespace rerun diff --git a/rerun_cpp/src/rerun/datatypes/tensor_dimension_ext.cpp b/rerun_cpp/src/rerun/datatypes/tensor_dimension_ext.cpp deleted file mode 100644 index 6699700c5ae9..000000000000 --- a/rerun_cpp/src/rerun/datatypes/tensor_dimension_ext.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include -#include "tensor_dimension.hpp" - -// #define EDIT_EXTENSION - -namespace rerun { - namespace datatypes { - -#ifdef EDIT_EXTENSION - // - - /// Nameless dimension. - TensorDimension(size_t size_) : size(size_) {} - - /// Dimension with name. - TensorDimension(size_t size_, std::string name_) : size(size_), name(std::move(name_)) {} - - // -#endif - } // namespace datatypes -} // namespace rerun diff --git a/rerun_py/README.md b/rerun_py/README.md index 92678ac6b1dc..d86ad3f7c513 100644 --- a/rerun_py/README.md +++ b/rerun_py/README.md @@ -89,3 +89,8 @@ While we try to keep the main branch usable at all times, it may be unstable occ ```sh pixi run -e py py-build && pixi run -e py py-test ``` + +# Running specific Python unit tests +```sh +pixi run -e py py-build && pixi run -e py pytest rerun_py/tests/unit/test_tensor.py +``` diff --git a/rerun_py/rerun_sdk/rerun/_validators.py b/rerun_py/rerun_sdk/rerun/_validators.py index 324a0799e440..1ea9535dc2cd 100644 --- a/rerun_py/rerun_sdk/rerun/_validators.py +++ b/rerun_py/rerun_sdk/rerun/_validators.py @@ -5,7 +5,7 @@ import numpy as np import numpy.typing as npt -from ._converters import to_np_float32, to_np_float64, to_np_uint32 +from ._converters import to_np_float32, to_np_float64, to_np_uint32, to_np_uint64 # This code is a straight port from Rust. @@ -67,6 +67,13 @@ def flat_np_uint32_array_from_array_like(data: Any, dimension: int) -> npt.NDArr return flat_np_array_from_array_like(array, dimension) +def flat_np_uint64_array_from_array_like(data: Any, dimension: int) -> npt.NDArray[np.uint64]: + """Converts to a flat uint numpy array from an arbitrary vector, validating for an expected dimensionality.""" + + array = to_np_uint64(data) + return flat_np_array_from_array_like(array, dimension) + + def flat_np_array_from_array_like(array: npt.NDArray[Any], dimension: int) -> npt.NDArray[Any]: """Converts to a flat numpy array from an arbitrary vector, validating for an expected dimensionality.""" diff --git a/rerun_py/rerun_sdk/rerun/archetypes/bar_chart_ext.py b/rerun_py/rerun_sdk/rerun/archetypes/bar_chart_ext.py index 20d1198e8b98..f066f3098749 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/bar_chart_ext.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/bar_chart_ext.py @@ -21,7 +21,7 @@ def values__field_converter_override(data: TensorDataArrayLike) -> TensorDataBat # TODO(jleibs): Doing this on raw arrow data is not great. Clean this up # once we coerce to a canonical non-arrow type. - shape_dims = tensor_data.as_arrow_array()[0][0].values.field(0).to_numpy() + shape_dims = tensor_data.as_arrow_array()[0][0].values.to_numpy() if len([d for d in shape_dims if d != 1]) != 1: _send_warning_or_raise( diff --git a/rerun_py/rerun_sdk/rerun/archetypes/tensor_ext.py b/rerun_py/rerun_sdk/rerun/archetypes/tensor_ext.py index 0ee17ce0edab..14531279ff6c 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/tensor_ext.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/tensor_ext.py @@ -18,7 +18,7 @@ def __init__( self: Any, data: TensorDataLike | TensorLike | None = None, *, - dim_names: Sequence[str | None] | None = None, + dim_names: Sequence[str] | None = None, value_range: Range1DLike | None = None, ): """ @@ -36,11 +36,11 @@ def __init__( ---------- self: The TensorData object to construct. - data: TensorDataLike | None + data: A TensorData object, or type that can be converted to a numpy array. - dim_names: Sequence[str] | None + dim_names: The names of the tensor dimensions when generating the shape from an array. - value_range: Sequence[float] | None + value_range: The range of values to use for colormapping. If not specified, the range will be estimated from the data. diff --git a/rerun_py/rerun_sdk/rerun/datatypes/.gitattributes b/rerun_py/rerun_sdk/rerun/datatypes/.gitattributes index dcfe4dfeec99..c3a9b1f6cc22 100644 --- a/rerun_py/rerun_sdk/rerun/datatypes/.gitattributes +++ b/rerun_py/rerun_sdk/rerun/datatypes/.gitattributes @@ -29,7 +29,6 @@ rgba32.py linguist-generated=true rotation_axis_angle.py linguist-generated=true tensor_buffer.py linguist-generated=true tensor_data.py linguist-generated=true -tensor_dimension.py linguist-generated=true tensor_dimension_index_selection.py linguist-generated=true tensor_dimension_selection.py linguist-generated=true time_int.py linguist-generated=true diff --git a/rerun_py/rerun_sdk/rerun/datatypes/__init__.py b/rerun_py/rerun_sdk/rerun/datatypes/__init__.py index 1cf1156f07c8..49397b6713b3 100644 --- a/rerun_py/rerun_sdk/rerun/datatypes/__init__.py +++ b/rerun_py/rerun_sdk/rerun/datatypes/__init__.py @@ -39,7 +39,6 @@ ) from .tensor_buffer import TensorBuffer, TensorBufferArrayLike, TensorBufferBatch, TensorBufferLike from .tensor_data import TensorData, TensorDataArrayLike, TensorDataBatch, TensorDataLike -from .tensor_dimension import TensorDimension, TensorDimensionArrayLike, TensorDimensionBatch, TensorDimensionLike from .tensor_dimension_index_selection import ( TensorDimensionIndexSelection, TensorDimensionIndexSelectionArrayLike, @@ -185,14 +184,10 @@ "TensorDataArrayLike", "TensorDataBatch", "TensorDataLike", - "TensorDimension", - "TensorDimensionArrayLike", - "TensorDimensionBatch", "TensorDimensionIndexSelection", "TensorDimensionIndexSelectionArrayLike", "TensorDimensionIndexSelectionBatch", "TensorDimensionIndexSelectionLike", - "TensorDimensionLike", "TensorDimensionSelection", "TensorDimensionSelectionArrayLike", "TensorDimensionSelectionBatch", diff --git a/rerun_py/rerun_sdk/rerun/datatypes/tensor_data.py b/rerun_py/rerun_sdk/rerun/datatypes/tensor_data.py index fa8e1e8364a5..28e3f52c428f 100644 --- a/rerun_py/rerun_sdk/rerun/datatypes/tensor_data.py +++ b/rerun_py/rerun_sdk/rerun/datatypes/tensor_data.py @@ -7,6 +7,7 @@ from typing import TYPE_CHECKING, Any, Sequence, Union +import numpy as np import numpy.typing as npt import pyarrow as pa from attrs import define, field @@ -15,6 +16,9 @@ from .._baseclasses import ( BaseBatch, ) +from .._converters import ( + to_np_uint64, +) from .tensor_data_ext import TensorDataExt __all__ = ["TensorData", "TensorDataArrayLike", "TensorDataBatch", "TensorDataLike"] @@ -46,8 +50,8 @@ class TensorData(TensorDataExt): # __init__ can be found in tensor_data_ext.py - shape: list[datatypes.TensorDimension] = field() - # The shape of the tensor, including optional names for each dimension. + shape: npt.NDArray[np.uint64] = field(converter=to_np_uint64) + # The shape of the tensor, i.e. the length of each dimension. # # (Docstring intentionally commented out to hide this field from the docs) @@ -56,6 +60,17 @@ class TensorData(TensorDataExt): # # (Docstring intentionally commented out to hide this field from the docs) + names: list[str] | None = field(default=None) + # The names of the dimensions of the tensor (optional). + # + # If set, should be the same length as [`datatypes.TensorData.shape`][rerun.datatypes.TensorData.shape]. + # If it has a different length your names may show up improperly, + # and some constructors may produce a warning or even an error. + # + # Example: `["height", "width", "channel", "batch"]`. + # + # (Docstring intentionally commented out to hide this field from the docs) + if TYPE_CHECKING: TensorDataLike = Union[TensorData, npt.ArrayLike] @@ -68,20 +83,10 @@ class TensorData(TensorDataExt): class TensorDataBatch(BaseBatch[TensorDataArrayLike]): _ARROW_DATATYPE = pa.struct([ pa.field( - "shape", - pa.list_( - pa.field( - "item", - pa.struct([ - pa.field("size", pa.uint64(), nullable=False, metadata={}), - pa.field("name", pa.utf8(), nullable=True, metadata={}), - ]), - nullable=False, - metadata={}, - ) - ), - nullable=False, - metadata={}, + "shape", pa.list_(pa.field("item", pa.uint64(), nullable=False, metadata={})), nullable=False, metadata={} + ), + pa.field( + "names", pa.list_(pa.field("item", pa.utf8(), nullable=False, metadata={})), nullable=True, metadata={} ), pa.field( "buffer", diff --git a/rerun_py/rerun_sdk/rerun/datatypes/tensor_data_ext.py b/rerun_py/rerun_sdk/rerun/datatypes/tensor_data_ext.py index 5d89c7f050fe..64dd756cf60e 100644 --- a/rerun_py/rerun_sdk/rerun/datatypes/tensor_data_ext.py +++ b/rerun_py/rerun_sdk/rerun/datatypes/tensor_data_ext.py @@ -8,6 +8,7 @@ import numpy.typing as npt import pyarrow as pa +from rerun._validators import flat_np_uint64_array_from_array_like from rerun.error_utils import _send_warning_or_raise from .._unions import build_dense_union @@ -20,7 +21,7 @@ def numpy(self, force: bool) -> npt.NDArray[Any]: ... if TYPE_CHECKING: - from . import TensorBufferLike, TensorDataArrayLike, TensorDataLike, TensorDimension, TensorDimensionLike + from . import TensorBufferLike, TensorDataArrayLike, TensorDataLike TensorLike = Union[TensorDataLike, TorchTensorLike] """Type helper for a tensor-like object that can be logged to Rerun.""" @@ -48,10 +49,10 @@ class TensorDataExt: def __init__( self: Any, *, - shape: Sequence[TensorDimensionLike] | None = None, + shape: Sequence[int] | None = None, buffer: TensorBufferLike | None = None, array: TensorLike | None = None, - dim_names: Sequence[str | None] | None = None, + dim_names: Sequence[str] | None = None, ) -> None: """ Construct a `TensorData` object. @@ -64,18 +65,18 @@ def __init__( Parameters ---------- - self: TensorData + self: The TensorData object to construct. - shape: Sequence[TensorDimensionLike] | None + shape: The shape of the tensor. If None, and an array is provided, the shape will be inferred from the shape of the array. - buffer: TensorBufferLike | None + buffer: The buffer of the tensor. If None, and an array is provided, the buffer will be generated from the array. - array: Tensor | None + array: A numpy array (or The array of the tensor. If None, the array will be inferred from the buffer. - dim_names: Sequence[str] | None - The names of the tensor dimensions when generating the shape from an array. + dim_names: + The names of the tensor dimensions. """ if array is None and buffer is None: @@ -84,10 +85,8 @@ def __init__( raise ValueError("Can only provide one of 'array' or 'buffer'") if buffer is not None and shape is None: raise ValueError("If 'buffer' is provided, 'shape' is also required") - if shape is not None and dim_names is not None: - raise ValueError("Can only provide one of 'shape' or 'names'") - from . import TensorBuffer, TensorDimension + from . import TensorBuffer from .tensor_data import _tensor_data__buffer__special_field_converter_override if shape is not None: @@ -101,7 +100,7 @@ def __init__( # If a shape we provided, it must match the array if resolved_shape: - shape_tuple = tuple(d.size for d in resolved_shape) + shape_tuple = tuple(d for d in resolved_shape) if shape_tuple != array.shape: _send_warning_or_raise( ( @@ -113,21 +112,10 @@ def __init__( resolved_shape = None if resolved_shape is None: - if dim_names: - if len(array.shape) != len(dim_names): - _send_warning_or_raise( - ( - f"len(array.shape) = {len(array.shape)} != " - + f"len(dim_names) = {len(dim_names)}. Dropping tensor dimension names." - ), - 2, - ) - resolved_shape = [TensorDimension(size, name) for size, name in zip(array.shape, dim_names)] # type: ignore[arg-type] - else: - resolved_shape = [TensorDimension(size) for size in array.shape] + resolved_shape = [size for size in array.shape] if resolved_shape is not None: - self.shape = resolved_shape + self.shape: npt.NDArray[np.uint64] = resolved_shape else: # This shouldn't be possible but typing can't figure it out raise ValueError("No shape provided.") @@ -137,7 +125,20 @@ def __init__( elif array is not None: self.buffer = TensorBuffer(array.flatten()) - expected_buffer_size = prod(d.size for d in self.shape) + self.names: list[str] | None = None + if dim_names: + if len(self.shape) == len(dim_names): + self.names = dim_names + else: + _send_warning_or_raise( + ( + f"len(shape) = {len(self.shape)} != " + + f"len(dim_names) = {len(dim_names)}. Ignoring tensor dimension names." + ), + 2, + ) + + expected_buffer_size = prod(d for d in self.shape) if len(self.buffer.inner) != expected_buffer_size: raise ValueError( f"Shape and buffer size do not match. {len(self.buffer.inner)} {self.shape}->{expected_buffer_size}" @@ -166,20 +167,26 @@ def native_to_pa_array_override(data: TensorDataArrayLike, data_type: pa.DataTyp data = TensorData(array=array) # Now build the actual arrow fields - shape = _build_shape_array(data.shape).cast(data_type.field("shape").type) + shape = pa.array([flat_np_uint64_array_from_array_like(data.shape, 1)], type=data_type.field("shape").type) buffer = _build_buffer_array(data.buffer) + if data.names is None: + names = pa.array([None], type=data_type.field("names").type) + else: + names = pa.array([data.names], type=data_type.field("names").type) + return pa.StructArray.from_arrays( [ shape, + names, buffer, ], - fields=[data_type.field("shape"), data_type.field("buffer")], + fields=data_type.fields, ).cast(data_type) def numpy(self: Any, force: bool) -> npt.NDArray[Any]: """Convert the TensorData back to a numpy array.""" - dims = [d.size for d in self.shape] + dims = [d for d in self.shape] return self.buffer.inner.reshape(dims) # type: ignore[no-any-return] @@ -188,26 +195,6 @@ def numpy(self: Any, force: bool) -> npt.NDArray[Any]: ################################################################################ -def _build_shape_array(dims: list[TensorDimension]) -> pa.Array: - from . import TensorDimensionBatch - - data_type = TensorDimensionBatch._ARROW_DATATYPE - - array = np.asarray([d.size for d in dims], dtype=np.uint64).flatten() - names = pa.array([d.name for d in dims], mask=[d is None for d in dims], type=data_type.field("name").type) - - return pa.ListArray.from_arrays( - offsets=[0, len(array)], - values=pa.StructArray.from_arrays( - [ - array, - names, - ], - fields=[data_type.field("size"), data_type.field("name")], - ), - ) - - DTYPE_MAP: Final[dict[npt.DTypeLike, str]] = { np.uint8: "U8", np.uint16: "U16", diff --git a/rerun_py/rerun_sdk/rerun/datatypes/tensor_dimension.py b/rerun_py/rerun_sdk/rerun/datatypes/tensor_dimension.py deleted file mode 100644 index 99b1b0977ec3..000000000000 --- a/rerun_py/rerun_sdk/rerun/datatypes/tensor_dimension.py +++ /dev/null @@ -1,71 +0,0 @@ -# DO NOT EDIT! This file was auto-generated by crates/build/re_types_builder/src/codegen/python/mod.rs -# Based on "crates/store/re_types/definitions/rerun/datatypes/tensor_dimension.fbs". - -# You can extend this class by creating a "TensorDimensionExt" class in "tensor_dimension_ext.py". - -from __future__ import annotations - -from typing import Any, Sequence, Union - -import pyarrow as pa -from attrs import define, field - -from .._baseclasses import ( - BaseBatch, -) -from .._converters import ( - str_or_none, -) - -__all__ = ["TensorDimension", "TensorDimensionArrayLike", "TensorDimensionBatch", "TensorDimensionLike"] - - -@define(init=False) -class TensorDimension: - """**Datatype**: A single dimension within a multi-dimensional tensor.""" - - def __init__(self: Any, size: int, name: str | None = None): - """ - Create a new instance of the TensorDimension datatype. - - Parameters - ---------- - size: - The length of this dimension. - name: - The name of this dimension, e.g. "width", "height", "channel", "batch', …. - - """ - - # You can define your own __init__ function as a member of TensorDimensionExt in tensor_dimension_ext.py - self.__attrs_init__(size=size, name=name) - - size: int = field(converter=int) - # The length of this dimension. - # - # (Docstring intentionally commented out to hide this field from the docs) - - name: str | None = field(default=None, converter=str_or_none) - # The name of this dimension, e.g. "width", "height", "channel", "batch', …. - # - # (Docstring intentionally commented out to hide this field from the docs) - - -TensorDimensionLike = TensorDimension -TensorDimensionArrayLike = Union[ - TensorDimension, - Sequence[TensorDimensionLike], -] - - -class TensorDimensionBatch(BaseBatch[TensorDimensionArrayLike]): - _ARROW_DATATYPE = pa.struct([ - pa.field("size", pa.uint64(), nullable=False, metadata={}), - pa.field("name", pa.utf8(), nullable=True, metadata={}), - ]) - - @staticmethod - def _native_to_pa_array(data: TensorDimensionArrayLike, data_type: pa.DataType) -> pa.Array: - raise NotImplementedError( - "Arrow serialization of TensorDimension not implemented: We lack codegen for arrow-serialization of general structs" - ) # You need to implement native_to_pa_array_override in tensor_dimension_ext.py diff --git a/rerun_py/tests/unit/test_tensor.py b/rerun_py/tests/unit/test_tensor.py index 34dbf4ab6923..b55f1d0ec3b2 100644 --- a/rerun_py/tests/unit/test_tensor.py +++ b/rerun_py/tests/unit/test_tensor.py @@ -6,7 +6,7 @@ import pytest import rerun as rr from rerun.components import TensorData, TensorDataBatch -from rerun.datatypes import TensorBuffer, TensorDataLike, TensorDimension +from rerun.datatypes import TensorBuffer, TensorDataLike rng = np.random.default_rng(12345) RANDOM_TENSOR_SOURCE = rng.uniform(0.0, 1.0, (8, 6, 3, 5)) @@ -15,12 +15,8 @@ TENSOR_DATA_INPUTS: list[TensorDataLike] = [ # Full explicit construction TensorData( - shape=[ - TensorDimension(8, name="a"), - TensorDimension(6, name="b"), - TensorDimension(3, name="c"), - TensorDimension(5, name="d"), - ], + shape=[8, 6, 3, 5], + dim_names=["a", "b", "c", "d"], buffer=TensorBuffer(RANDOM_TENSOR_SOURCE), ), # Implicit construction from ndarray @@ -33,14 +29,15 @@ TensorData(array=RANDOM_TENSOR_SOURCE, dim_names=["a", "b", "c", "d"]), ] -# 0 = shape -# 1 = buffer +SHAPE = 0 # Based on datatypes/tensor_data.fbs +NAMES = 1 # Based on datatypes/tensor_data.fbs +BUFFER = 2 # Based on datatypes/tensor_data.fbs CHECK_FIELDS: list[list[int]] = [ - [0, 1], - [1], - [1], - [0, 1], - [0, 1], + [SHAPE, NAMES, BUFFER], + [BUFFER], + [BUFFER], + [SHAPE, NAMES, BUFFER], + [SHAPE, NAMES, BUFFER], ] @@ -87,12 +84,8 @@ def test_bad_tensors() -> None: # Wrong size buffer for dimensions with pytest.raises(ValueError): TensorData( - shape=[ - TensorDimension(8, name="a"), - TensorDimension(6, name="b"), - TensorDimension(3, name="c"), - TensorDimension(4, name="d"), - ], + shape=[1, 2, 3], + dim_names=["a", "b", "c", "d"], buffer=RANDOM_TENSOR_SOURCE, ) @@ -108,11 +101,7 @@ def test_bad_tensors() -> None: # Shape disagrees with array with pytest.raises(ValueError): TensorData( - shape=[ - TensorDimension(8, name="a"), - TensorDimension(6, name="b"), - TensorDimension(5, name="c"), - TensorDimension(3, name="d"), - ], + shape=[1, 2, 3], + dim_names=["a", "b", "c", "d"], array=RANDOM_TENSOR_SOURCE, ) diff --git a/tests/cpp/roundtrips/tensor/main.cpp b/tests/cpp/roundtrips/tensor/main.cpp index c1a218349a5f..98d367454b74 100644 --- a/tests/cpp/roundtrips/tensor/main.cpp +++ b/tests/cpp/roundtrips/tensor/main.cpp @@ -8,10 +8,10 @@ int main(int, char** argv) { const auto rec = rerun::RecordingStream("rerun_example_roundtrip_tensor"); rec.save(argv[1]).exit_on_failure(); - std::vector dimensions{{3, 4, 5, 6}}; + std::vector shape{{3, 4, 5, 6}}; std::vector data(360); std::generate(data.begin(), data.end(), [n = 0]() mutable { return n++; }); - rec.log("tensor", rerun::archetypes::Tensor(rerun::datatypes::TensorData{dimensions, data})); + rec.log("tensor", rerun::archetypes::Tensor(rerun::datatypes::TensorData{shape, data})); } diff --git a/tests/python/release_checklist/check_all_components_ui.py b/tests/python/release_checklist/check_all_components_ui.py index 0885c5010ccc..2819ee163442 100644 --- a/tests/python/release_checklist/check_all_components_ui.py +++ b/tests/python/release_checklist/check_all_components_ui.py @@ -218,7 +218,7 @@ def alternatives(self) -> list[Any] | None: rr.datatypes.TensorData(array=np.random.randint(0, 255, (5, 3, 6, 4), dtype=np.uint8)), rr.datatypes.TensorData( array=np.random.randint(0, 255, (5, 3, 6, 4), dtype=np.uint8), - dim_names=[None, "hello", None, "world"], + dim_names=["hello", "brave", "new", "world"], ), rr.datatypes.TensorData(array=np.random.randint(0, 255, (5, 3, 6, 4, 3), dtype=np.uint8)), ] From e10d5bc608cbd922a604eaad928b7629c453ade2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jochen=20G=C3=B6rtler?= Date: Wed, 18 Dec 2024 15:09:43 +0100 Subject: [PATCH 25/30] Add `grtlr` to list of `OFFICIAL_RERUN_DEVS` (#8485) --- scripts/generate_changelog.py | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/generate_changelog.py b/scripts/generate_changelog.py index 40556952af3d..61c58a418e0d 100755 --- a/scripts/generate_changelog.py +++ b/scripts/generate_changelog.py @@ -29,6 +29,7 @@ "abey79", "emilk", "gavrelina", + "grtlr", "jleibs", "jprochazk", "nikolausWest", From efcb2f5ab842b2e287d5a58a4d7d4a01584db6ac Mon Sep 17 00:00:00 2001 From: Antoine Beyeler <49431240+abey79@users.noreply.github.com> Date: Wed, 18 Dec 2024 15:23:29 +0100 Subject: [PATCH 26/30] Remove manual truncation of tensor shape UI (#8531) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### Related * fixes #8525 ### What Truncation now happens at egui test level, so we no longer need that manual truncation code. (This code is soon going to disappear anyways but at least it'll disappear in a good state 🀷🏻) ![image](https://github.com/user-attachments/assets/ee8c0d00-1ff3-4e2c-8154-41c2e1c58bae) --- crates/viewer/re_data_ui/src/tensor.rs | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/crates/viewer/re_data_ui/src/tensor.rs b/crates/viewer/re_data_ui/src/tensor.rs index badbb7f541b9..8d21b1c1d45c 100644 --- a/crates/viewer/re_data_ui/src/tensor.rs +++ b/crates/viewer/re_data_ui/src/tensor.rs @@ -9,13 +9,13 @@ use re_viewer_context::{TensorStats, TensorStatsCache, UiLayout, ViewerContext}; use super::EntityDataUi; fn format_tensor_shape_single_line(tensor: &TensorData) -> String { - const MAX_SHOWN: usize = 4; // should be enough for width/height/depth and then some! - let short_shape = &tensor.shape[0..tensor.shape.len().min(MAX_SHOWN)]; - let has_names = short_shape + let has_names = tensor + .shape .iter() .enumerate() .any(|(dim_idx, _)| tensor.dim_name(dim_idx).is_some()); - let shapes = short_shape + tensor + .shape .iter() .enumerate() .map(|(dim_idx, dim_len)| { @@ -29,19 +29,7 @@ fn format_tensor_shape_single_line(tensor: &TensorData) -> String { } ) }) - .join(if has_names { " Γ— " } else { "Γ—" }); - format!( - "{shapes}{}", - if MAX_SHOWN < tensor.shape.len() { - if has_names { - " Γ— …" - } else { - "×…" - } - } else { - "" - } - ) + .join(if has_names { " Γ— " } else { "Γ—" }) } impl EntityDataUi for re_types::components::TensorData { From 905c2fcf8a0697b36afce6d2e52a0d9c73c29ad0 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Wed, 18 Dec 2024 16:36:03 +0100 Subject: [PATCH 27/30] Fix: `./scripts/lint.py` ignored all under `crates/build` (#8532) --- .gitignore | 2 +- crates/build/re_protos_builder/src/lib.rs | 2 +- crates/build/re_types_builder/src/codegen/rust/arrow.rs | 2 +- crates/build/re_types_builder/src/codegen/rust/serializer.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 43b4208ba656..06d4384f6e35 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,7 @@ __MACOSX *.bin *.o /arrow/ -/build/ +./build/ **/build-msvc/ **/CMakeFiles/ **/CMakeCache.txt diff --git a/crates/build/re_protos_builder/src/lib.rs b/crates/build/re_protos_builder/src/lib.rs index 6f382e89fb48..ddbbce158a99 100644 --- a/crates/build/re_protos_builder/src/lib.rs +++ b/crates/build/re_protos_builder/src/lib.rs @@ -32,7 +32,7 @@ pub fn generate_rust_code( std::process::exit(1); } _ => { - panic!("{err:?}"); + panic!("{err}"); } } } diff --git a/crates/build/re_types_builder/src/codegen/rust/arrow.rs b/crates/build/re_types_builder/src/codegen/rust/arrow.rs index 890f9d95004b..303dbf684637 100644 --- a/crates/build/re_types_builder/src/codegen/rust/arrow.rs +++ b/crates/build/re_types_builder/src/codegen/rust/arrow.rs @@ -7,7 +7,7 @@ use quote::quote; /// `(Datatype, is_recursive)` /// /// If `is_recursive` is set to `true`, -/// then the generate code will often be shorter, as it it will +/// then the generated code will often be shorter, as it will /// defer to calling `arrow_datatype()` on the inner type. pub struct ArrowDataTypeTokenizer<'a>(pub &'a ::arrow2::datatypes::DataType, pub bool); diff --git a/crates/build/re_types_builder/src/codegen/rust/serializer.rs b/crates/build/re_types_builder/src/codegen/rust/serializer.rs index 8f8063923dc4..6156c4895bc4 100644 --- a/crates/build/re_types_builder/src/codegen/rust/serializer.rs +++ b/crates/build/re_types_builder/src/codegen/rust/serializer.rs @@ -843,7 +843,7 @@ fn quote_arrow_field_serializer( // if we make the C++ and Python codegen match the rust behavior or // make our comparison tests more lenient. // - // This workaround does not apply if we don't have any validity validity on the outer type. + // This workaround does not apply if we don't have any validity on the outer type. // (as it is always the case with unions where the nullability is encoded as a separate variant) let quoted_inner_validity = if let (true, DataType::FixedSizeList(_, count)) = (elements_are_nullable, datatype.to_logical_type()) From 8839f9c8df51c970de427c958b6417362bc2a63d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= Date: Wed, 18 Dec 2024 18:22:15 +0100 Subject: [PATCH 28/30] Update colab notebook link (#8535) --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ec762a5278db..f11e5db8cde3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -189,7 +189,7 @@ jobs: - [ ] cargo install of cli tool: does it install and run? - [ ] C++ SDK zip: does it contain rerun_c for all platforms? - [ ] Populate the release with the changelog and a nice header video/picture, check `Set as latest release`, then click `Publish release`. - - [ ] Update the [google colab notebooks](https://drive.google.com/drive/folders/0AC0q24MFKh3fUk9PVA) to install this version and re-execute the notebook. + - [ ] Update the [google colab notebooks](https://colab.research.google.com/drive/1R9I7s4o6wydQC_zkybqaSRFTtlEaked_) to install this version and re-execute the notebook. - [ ] Update landing's version of the web viewer (@jprochazk) A few hours after the GitHub release is created, `regro-cf-autotick-bot` will create a From 204fef00fae1b3a9d4f095e0f23b189420cedcd5 Mon Sep 17 00:00:00 2001 From: rerun-bot <132550499+rerun-bot@users.noreply.github.com> Date: Thu, 19 Dec 2024 09:40:07 +0100 Subject: [PATCH 29/30] Release 0.21.0 (#8484) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Clement Rey Co-authored-by: Andreas Reich Co-authored-by: Katerina Gavrilo Co-authored-by: Jochen GΓΆrtler --- CHANGELOG.md | 176 +++++++++++++ Cargo.lock | 231 +++++++++--------- Cargo.toml | 131 +++++----- .../src/codegen/docs/snippets_ref.rs | 3 +- .../rerun/archetypes/ellipsoids3d.fbs | 2 +- .../rerun/archetypes/graph_edges.fbs | 4 +- .../rerun/archetypes/graph_nodes.fbs | 4 +- .../blueprint/archetypes/near_clip_plane.fbs | 1 - .../blueprint/components/near_clip_plane.fbs | 3 +- .../rerun/blueprint/views/graph.fbs | 3 +- .../rerun/components/graph_edge.fbs | 1 - .../rerun/components/graph_node.fbs | 1 - .../rerun/components/graph_type.fbs | 1 - .../definitions/rerun/components/plane3d.fbs | 1 - .../rerun/components/recording_uri.fbs | 3 +- .../definitions/rerun/datatypes/plane3d.fbs | 1 - .../definitions/rerun/datatypes/utf8_pair.fbs | 1 - .../re_types/src/archetypes/ellipsoids3d.rs | 52 ++++ .../re_types/src/archetypes/graph_edges.rs | 2 - .../re_types/src/archetypes/graph_nodes.rs | 2 - crates/store/re_types/src/reflection/mod.rs | 45 ++-- crates/utils/re_capabilities/README.md | 2 +- crates/viewer/re_view/README.md | 2 +- crates/viewer/re_view_bar_chart/README.md | 2 +- crates/viewer/re_view_dataframe/README.md | 2 +- crates/viewer/re_view_graph/README.md | 6 +- crates/viewer/re_view_map/README.md | 4 +- crates/viewer/re_view_spatial/README.md | 4 +- crates/viewer/re_view_tensor/README.md | 4 +- crates/viewer/re_view_text_document/README.md | 4 +- crates/viewer/re_view_text_log/README.md | 4 +- crates/viewer/re_view_time_series/README.md | 4 +- crates/viewer/re_viewer/README.md | 4 +- crates/viewer/re_viewer_context/Cargo.toml | 1 + crates/viewer/re_viewer_context/README.md | 4 +- crates/viewer/re_viewport/README.md | 4 +- crates/viewer/re_viewport_blueprint/README.md | 4 +- docs/content/howto/logging/send-columns.md | 2 +- .../reference/migration/migration-0-21.md | 11 +- .../reference/types/archetypes/graph_edges.md | 9 +- .../reference/types/archetypes/graph_nodes.md | 9 +- .../reference/types/components/color.md | 2 +- .../reference/types/components/graph_edge.md | 8 +- .../reference/types/components/graph_node.md | 8 +- .../reference/types/components/graph_type.md | 8 +- .../reference/types/components/plane3d.md | 6 +- .../reference/types/components/position2d.md | 2 +- .../reference/types/components/radius.md | 2 +- .../types/components/recording_uri.md | 6 +- .../reference/types/components/show_labels.md | 2 +- .../reference/types/components/text.md | 2 +- .../reference/types/datatypes/plane3d.md | 8 +- .../content/reference/types/datatypes/utf8.md | 6 +- .../reference/types/datatypes/utf8pair.md | 8 +- .../reference/types/views/graph_view.md | 2 +- docs/snippets/INDEX.md | 44 ++-- examples/python/graph_lattice/README.md | 4 +- .../python/graph_lattice/graph_lattice.py | 2 +- examples/python/graphs/README.md | 4 +- examples/python/graphs/graphs.py | 2 +- examples/rust/clock/Cargo.toml | 2 +- examples/rust/custom_data_loader/Cargo.toml | 2 +- .../rust/custom_store_subscriber/Cargo.toml | 2 +- examples/rust/custom_view/Cargo.toml | 2 +- examples/rust/dataframe_query/Cargo.toml | 2 +- examples/rust/dna/Cargo.toml | 2 +- examples/rust/extend_viewer_ui/Cargo.toml | 2 +- examples/rust/external_data_loader/Cargo.toml | 2 +- examples/rust/graph_lattice/Cargo.toml | 2 +- examples/rust/graph_lattice/README.md | 4 +- examples/rust/incremental_logging/Cargo.toml | 2 +- examples/rust/log_file/Cargo.toml | 2 +- examples/rust/minimal/Cargo.toml | 2 +- examples/rust/minimal_options/Cargo.toml | 2 +- examples/rust/minimal_serve/Cargo.toml | 2 +- examples/rust/objectron/Cargo.toml | 2 +- examples/rust/raw_mesh/Cargo.toml | 2 +- examples/rust/shared_recording/Cargo.toml | 2 +- examples/rust/spawn_viewer/Cargo.toml | 2 +- examples/rust/stdio/Cargo.toml | 2 +- examples/rust/template/Cargo.toml | 2 +- pixi.lock | 10 +- .../src/rerun/archetypes/ellipsoids3d.hpp | 55 +++++ .../src/rerun/archetypes/graph_edges.hpp | 2 - .../src/rerun/archetypes/graph_nodes.hpp | 2 - rerun_cpp/src/rerun/c/sdk_info.h | 4 +- rerun_js/web-viewer-react/README.md | 2 +- rerun_js/web-viewer-react/package.json | 4 +- rerun_js/web-viewer/README.md | 2 +- rerun_js/web-viewer/package.json | 2 +- rerun_notebook/pyproject.toml | 2 +- rerun_py/pyproject.toml | 2 +- rerun_py/rerun_sdk/rerun/__init__.py | 4 +- .../rerun/archetypes/ellipsoids3d.py | 34 +++ .../rerun_sdk/rerun/archetypes/graph_edges.py | 2 - .../rerun_sdk/rerun/archetypes/graph_nodes.py | 2 - scripts/ci/crates.py | 2 +- .../check_hover_select_reset.py | 3 - 98 files changed, 669 insertions(+), 389 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a94fc73a0c0d..6f40cd8ec176 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,182 @@ ## [Unreleased](https://github.com/rerun-io/rerun/compare/latest...HEAD) +## [0.21.0](https://github.com/rerun-io/rerun/compare/0.20.3...0.21.0) - Graph view, 3D Grid & UI/UX improvements + +πŸ“– Release blogpost: https://rerun.io/blog/graphs + +🧳 Migration guide: https://rerun.io/docs/reference/migration/migration-0-21 + +### ✨ Overview & highlights + +#### Graph view + +We've added two new logging primitives: [`GraphNodes`](https://rerun.io/docs/reference/types/archetypes/graph_nodes) and [`GraphEdges`](https://rerun.io/docs/reference/types/archetypes/graph_edges) that can be used to visualize node-link diagrams. For this, we have implemented a new Graph View that uses force-based layouts to draw graphs. + +This video demonstrates the main features of the new graph view: + +https://github.com/user-attachments/assets/77db75c9-a8d8-401d-b90d-3daf08baf0ba + +You can also have a look at https://github.com/rerun-io/rerun/pull/7500 if you want to learn to more. + +#### UX improvements + +This video demonstrates the main UX improvements that went into this release: + +https://github.com/user-attachments/assets/bef071b5-0681-41b2-9ef0-1c6a557ff138 + +#### 3D grid + +The 3D view now offers an infinite 3D grid, enabled by default. Further controls and settings are available as usual through the blueprint API and/or the selection panel. + +

+ + + +

+ +All the nitty gritty details in https://github.com/rerun-io/rerun/pull/8230 and https://github.com/rerun-io/rerun/pull/8234. + +#### Undo/Redo support & many more UI/UX improvements + +You can now undo/redo blueprint changes in the viewer! +Watch [@emilk](https://github.com/emilk/) putting it to action and explains how it works: + +https://github.com/user-attachments/assets/a29c099d-35a3-4d32-8946-932b5a184943 + + +#### Other UX improvements + +But that's not the only thing that improved in the viewer: +* Breadcrumbs show up in the selection menu now + + ![image](https://github.com/user-attachments/assets/c1d20eb1-f259-4b43-89d4-b9fdc75dc88c) + +* Take screenshots of views from context menus + + ![image](https://github.com/user-attachments/assets/6c50e6f0-330f-43f7-a393-65dd47aa171b) + +* Entities can now be dragged from Blueprint & Streams panel into views + + ![image](https://github.com/user-attachments/assets/493d9711-c4d1-407e-ab41-eef2e4e51ba8) + +#### Index of code snippets + +We now have a new [index for all our code snippets](./docs/snippets/INDEX.md). + +You can use it to quickly find copy-pastable snippets of code for any Rerun feature you're interested in (API, Archetypes, Components, etc). +No special tools required -- all you need is a keyword of interest, and plain old text search. + +It's still the early days so it is far from perfect, but we think it can already be quite helpful; feedback welcome. +Most of it is auto-generated, so it will never get out of sync! + +### ⚠️ Breaking changes + +* Near clip plane for `Spatial2D` views now defaults to `0.1` in 3D scene units. +* Blueprint: types and fields got renamed from `.*space_view.*`/`.*SpaceView.*` to `.*view.*`/`.*View.*`. +* 3D transform arrow visualization show up less often by default. +* `DisconnectedSpace` archetype/component is deprecated in favor of implicit invalid transforms (like zero scale or zero rotation matrix). +* `RotationAxisAngle` with zero rotation axis is no longer treated as identity. + +Read our 🧳 migration guide for more detailed information: https://rerun.io/docs/reference/migration/migration-0-21. + +### πŸ”Ž Details + +#### πŸͺ΅ Log API +- End-to-end tagging: Rust [#8304](https://github.com/rerun-io/rerun/pull/8304) +- Encode `LogMsg` using protobuf [#8347](https://github.com/rerun-io/rerun/pull/8347) + +#### 🌊 C++ API +- End-to-end tagging: C++ [#8316](https://github.com/rerun-io/rerun/pull/8316) + +#### 🐍 Python API +- Never direct users towards using `rr.log_components` [#8151](https://github.com/rerun-io/rerun/pull/8151) +- Make it possible to log custom components using `rr.send_columns` [#8163](https://github.com/rerun-io/rerun/pull/8163) +- Lint and fix python SDK `(Py)RecordingStream` upcasting issues [#8184](https://github.com/rerun-io/rerun/pull/8184) +- End-to-end tagging: Python [#8298](https://github.com/rerun-io/rerun/pull/8298) +- Rename space view to view everywhere [#8396](https://github.com/rerun-io/rerun/pull/8396) +- Fix broken notebook loading on firefox by compressing the encoded wasm payload [#8426](https://github.com/rerun-io/rerun/pull/8426) +- Add utility to `rr.components.Color` to generate colors from any string (and use it in the air traffic data example) [#8458](https://github.com/rerun-io/rerun/pull/8458) +- Introduce new API to send a dataframe to Rerun [#8461](https://github.com/rerun-io/rerun/pull/8461) + +#### πŸ¦€ Rust API +- Update MSRV to 1.80 [#8178](https://github.com/rerun-io/rerun/pull/8178) +- Remove `Loggable::NAME` -- Loggables do not have any semantics [#8082](https://github.com/rerun-io/rerun/pull/8082) +- Never direct users towards using `RecordingStream::log_component_batches` [#8149](https://github.com/rerun-io/rerun/pull/8149) +- Rust API: be explicit about when we're using the arrow2 crate [#8194](https://github.com/rerun-io/rerun/pull/8194) +- Add `from_gray16` for `DepthImage` [#8213](https://github.com/rerun-io/rerun/pull/8213) (thanks [@fawdlstty](https://github.com/fawdlstty)!) +- Rust: more `impl` helpers [#8401](https://github.com/rerun-io/rerun/pull/8401) + +#### πŸͺ³ Bug fixes +- Fix outlines for lines having more perceived aliasing since 0.20 [#8317](https://github.com/rerun-io/rerun/pull/8317) +- Fix handling unnormalized axis for (Pose)RotationAxisAngle [#8341](https://github.com/rerun-io/rerun/pull/8341) +- Fix 2D/3D view artifacts on view's border when using fractional zoom [#8369](https://github.com/rerun-io/rerun/pull/8369) + +#### 🌁 Viewer improvements +- World grid part 1/2: add world grid renderer to `re_renderer` [#8230](https://github.com/rerun-io/rerun/pull/8230) +- World grid part 2/2: Integrate into Viewer [#8234](https://github.com/rerun-io/rerun/pull/8234) +- Add Undo/Redo support in the viewer [#7546](https://github.com/rerun-io/rerun/pull/7546) +- Space view screenshotting in native viewer [#8258](https://github.com/rerun-io/rerun/pull/8258) +- Remove selection history [#8296](https://github.com/rerun-io/rerun/pull/8296) +- Make the near clipping plane editable in 2D views [#8348](https://github.com/rerun-io/rerun/pull/8348) +- Don't show transform arrows on all entities without any other visualizer [#8387](https://github.com/rerun-io/rerun/pull/8387) +- Do query for default components only once per view [#8424](https://github.com/rerun-io/rerun/pull/8424) +- Improve hovered order in 2D views [#8405](https://github.com/rerun-io/rerun/pull/8405) +- Remove wait-time when opening settings panel [#8464](https://github.com/rerun-io/rerun/pull/8464) +- Deprecate `DisconnectedSpace` archetype/component in favor of implicit invalid transforms [#8459](https://github.com/rerun-io/rerun/pull/8459) +- Improve graphics device capability detection, warn on old devices, early error on unsupported render targets [#8476](https://github.com/rerun-io/rerun/pull/8476) + +#### πŸ§‘β€πŸ« Examples +- Add a new "Air Traffic Data" example [#5449](https://github.com/rerun-io/rerun/pull/5449) +- Use video logging api in `detect_and_track` example [#8261](https://github.com/rerun-io/rerun/pull/8261) (thanks [@oxkitsune](https://github.com/oxkitsune)!) +- Add hloc_glomap example and update manifest [#8352](https://github.com/rerun-io/rerun/pull/8352) (thanks [@pablovela5620](https://github.com/pablovela5620)!) +- Introduce the Snippet Index [#8383](https://github.com/rerun-io/rerun/pull/8383) +- Implement complete Graph View example [#8421](https://github.com/rerun-io/rerun/pull/8421) + +#### πŸ“š Docs +- Update wheel build instruction [#8235](https://github.com/rerun-io/rerun/pull/8235) +- Fix various doc links in SDKs [#8331](https://github.com/rerun-io/rerun/pull/8331) + +#### πŸ–Ό UI improvements +- Implement graph components and archetypes [#7500](https://github.com/rerun-io/rerun/pull/7500) +- Add support for Bezier-curve multi (self-)edges [#8256](https://github.com/rerun-io/rerun/pull/8256) +- Implement incremental graph layouts [#8308](https://github.com/rerun-io/rerun/pull/8308) +- Revert label background color to that in 0.19 [#8337](https://github.com/rerun-io/rerun/pull/8337) +- Add selection hierarchy breadcrumbs [#8319](https://github.com/rerun-io/rerun/pull/8319) +- More compact selection panel when multiple items selected [#8351](https://github.com/rerun-io/rerun/pull/8351) +- Make Position2D components editable in selection panel [#8357](https://github.com/rerun-io/rerun/pull/8357) +- Dynamic configuration of graph layout forces through blueprints [#8299](https://github.com/rerun-io/rerun/pull/8299) +- Document legend interaction in the timeseries view help text [#8406](https://github.com/rerun-io/rerun/pull/8406) +- Allow drag-and-dropping multiple containers and views in the blueprint tree [#8334](https://github.com/rerun-io/rerun/pull/8334) +- Improve picking in 2D views [#8404](https://github.com/rerun-io/rerun/pull/8404) +- Make our collapsing triangle thinner for more consistency with our icons [#8408](https://github.com/rerun-io/rerun/pull/8408) +- Entities can be dragged from the blueprint tree and streams tree to an existing view in the viewport [#8431](https://github.com/rerun-io/rerun/pull/8431) + +#### 🎨 Renderer improvements +- Update egui to latest, update wgpu to 23.0.0 [#8183](https://github.com/rerun-io/rerun/pull/8183) + +#### ✨ Other enhancement +- Improve `rrd print`'s verbosity modes [#8392](https://github.com/rerun-io/rerun/pull/8392) +- Miscellaneous improvements to archetype reflection [#8432](https://github.com/rerun-io/rerun/pull/8432) +- Migration kernel for the blueprint space-view-related breaking changes [#8439](https://github.com/rerun-io/rerun/pull/8439) + +#### πŸ—£ Refactors +- Add arrow(1)-interface on top of `Loggable` and `ArrowBuffer` [#8197](https://github.com/rerun-io/rerun/pull/8197) +- `re_types_blueprint` -> `re_types::blueprint` [#8419](https://github.com/rerun-io/rerun/pull/8419) +- `re_viewer::reflection` -> `re_types::reflection` [#8420](https://github.com/rerun-io/rerun/pull/8420) + +#### πŸ“¦ Dependencies +- Numpy 2.0 allowed in pyproject.toml [#8306](https://github.com/rerun-io/rerun/pull/8306) (thanks [@Ipuch](https://github.com/Ipuch)!) +- Upgrade to egui 0.30 (+ ecosystem) [#8516](https://github.com/rerun-io/rerun/pull/8516) + +#### πŸ§‘β€πŸ’» Dev-experience +- Add `MainThreadToken` to ensure file-dialogs only run on the main thread [#8467](https://github.com/rerun-io/rerun/pull/8467) + +#### πŸ€·β€ Other +- Deprecate `--serve`, add `--serve-web` [#8144](https://github.com/rerun-io/rerun/pull/8144) +- Clean up pass over all superfluous hashing happening on the query path [#8207](https://github.com/rerun-io/rerun/pull/8207) +- Improve performance of time panel [#8224](https://github.com/rerun-io/rerun/pull/8224) + ## [0.20.3](https://github.com/rerun-io/rerun/compare/0.20.2...0.20.3) - Web viewer fix ### πŸ”Ž Details diff --git a/Cargo.lock b/Cargo.lock index 60076725fe56..12ac9a4c6699 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1381,7 +1381,7 @@ dependencies = [ [[package]] name = "clock" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", "clap", @@ -1724,7 +1724,7 @@ checksum = "96a6ac251f4a2aca6b3f91340350eab87ae57c3f127ffeb585e92bd336717991" [[package]] name = "custom_data_loader" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "re_build_tools", "rerun", @@ -1732,7 +1732,7 @@ dependencies = [ [[package]] name = "custom_store_subscriber" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "re_build_tools", "rerun", @@ -1740,7 +1740,7 @@ dependencies = [ [[package]] name = "custom_view" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "mimalloc", "re_crash_handler", @@ -1796,7 +1796,7 @@ checksum = "5c297a1c74b71ae29df00c3e22dd9534821d60eb9af5a0192823fa2acea70c2a" [[package]] name = "dataframe_query" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "itertools 0.13.0", "rerun", @@ -1891,7 +1891,7 @@ dependencies = [ [[package]] name = "dna" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "itertools 0.13.0", "rand", @@ -2395,7 +2395,7 @@ dependencies = [ [[package]] name = "extend_viewer_ui" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "mimalloc", "re_crash_handler", @@ -2928,7 +2928,7 @@ dependencies = [ [[package]] name = "graph_lattice" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", "clap", @@ -3520,7 +3520,7 @@ dependencies = [ [[package]] name = "incremental_logging" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", "clap", @@ -3951,7 +3951,7 @@ dependencies = [ [[package]] name = "log_benchmark" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", "clap", @@ -3962,7 +3962,7 @@ dependencies = [ [[package]] name = "log_file" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", "clap", @@ -4140,14 +4140,14 @@ dependencies = [ [[package]] name = "minimal" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "rerun", ] [[package]] name = "minimal_options" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", "clap", @@ -4157,7 +4157,7 @@ dependencies = [ [[package]] name = "minimal_serve" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "rerun", ] @@ -4758,7 +4758,7 @@ dependencies = [ [[package]] name = "objectron" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", "clap", @@ -4984,7 +4984,7 @@ dependencies = [ [[package]] name = "plot_dashboard_stress" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", "clap", @@ -5477,7 +5477,7 @@ checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" [[package]] name = "raw_mesh" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", "bytes", @@ -5520,7 +5520,7 @@ checksum = "3b42e27ef78c35d3998403c1d26f3efd9e135d3e5121b0a4845cc5cc27547f4f" [[package]] name = "re_analytics" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "crossbeam", "directories", @@ -5568,7 +5568,7 @@ dependencies = [ [[package]] name = "re_blueprint_tree" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "egui", "itertools 0.13.0", @@ -5587,14 +5587,14 @@ dependencies = [ [[package]] name = "re_build_info" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "serde", ] [[package]] name = "re_build_tools" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", "cargo_metadata 0.18.1", @@ -5607,7 +5607,7 @@ dependencies = [ [[package]] name = "re_capabilities" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "document-features", "egui", @@ -5616,14 +5616,14 @@ dependencies = [ [[package]] name = "re_case" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "convert_case", ] [[package]] name = "re_chunk" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "ahash", "anyhow", @@ -5652,7 +5652,7 @@ dependencies = [ [[package]] name = "re_chunk_store" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "ahash", "anyhow", @@ -5684,7 +5684,7 @@ dependencies = [ [[package]] name = "re_chunk_store_ui" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "egui", "egui_extras", @@ -5699,7 +5699,7 @@ dependencies = [ [[package]] name = "re_component_ui" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "egui", "egui_extras", @@ -5718,7 +5718,7 @@ dependencies = [ [[package]] name = "re_context_menu" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "egui", "egui_tiles", @@ -5739,7 +5739,7 @@ dependencies = [ [[package]] name = "re_crash_handler" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "backtrace", "econtext", @@ -5752,7 +5752,7 @@ dependencies = [ [[package]] name = "re_data_loader" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "ahash", "anyhow", @@ -5781,7 +5781,7 @@ dependencies = [ [[package]] name = "re_data_source" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", "itertools 0.13.0", @@ -5799,7 +5799,7 @@ dependencies = [ [[package]] name = "re_data_ui" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "ahash", "anyhow", @@ -5829,7 +5829,7 @@ dependencies = [ [[package]] name = "re_dataframe" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", "itertools 0.13.0", @@ -5853,7 +5853,7 @@ dependencies = [ [[package]] name = "re_dev_tools" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", "argh", @@ -5880,7 +5880,7 @@ dependencies = [ [[package]] name = "re_entity_db" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "ahash", "anyhow", @@ -5913,21 +5913,21 @@ dependencies = [ [[package]] name = "re_error" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", ] [[package]] name = "re_format" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "num-traits", ] [[package]] name = "re_format_arrow" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "comfy-table", "re_arrow2", @@ -5937,7 +5937,7 @@ dependencies = [ [[package]] name = "re_grpc_client" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "re_chunk", "re_error", @@ -5958,7 +5958,7 @@ dependencies = [ [[package]] name = "re_int_histogram" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "criterion", "insta", @@ -5969,7 +5969,7 @@ dependencies = [ [[package]] name = "re_log" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "env_logger", "js-sys", @@ -5982,7 +5982,7 @@ dependencies = [ [[package]] name = "re_log_encoding" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "criterion", "ehttp", @@ -6010,7 +6010,7 @@ dependencies = [ [[package]] name = "re_log_types" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "ahash", "anyhow", @@ -6059,7 +6059,7 @@ dependencies = [ [[package]] name = "re_memory" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "ahash", "backtrace", @@ -6094,7 +6094,7 @@ dependencies = [ [[package]] name = "re_protos" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "prost", "thiserror 1.0.65", @@ -6104,7 +6104,7 @@ dependencies = [ [[package]] name = "re_protos_builder" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "camino", "prost-build", @@ -6114,7 +6114,7 @@ dependencies = [ [[package]] name = "re_query" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "ahash", "anyhow", @@ -6168,7 +6168,7 @@ dependencies = [ [[package]] name = "re_renderer" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "ahash", "anyhow", @@ -6220,7 +6220,7 @@ dependencies = [ [[package]] name = "re_renderer_examples" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "ahash", "anyhow", @@ -6244,7 +6244,7 @@ dependencies = [ [[package]] name = "re_sdk" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "ahash", "crossbeam", @@ -6279,7 +6279,7 @@ dependencies = [ [[package]] name = "re_sdk_comms" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "ahash", "crossbeam", @@ -6295,7 +6295,7 @@ dependencies = [ [[package]] name = "re_selection_panel" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "egui", "egui_tiles", @@ -6322,7 +6322,7 @@ dependencies = [ [[package]] name = "re_smart_channel" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "crossbeam", "parking_lot", @@ -6333,7 +6333,7 @@ dependencies = [ [[package]] name = "re_string_interner" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "ahash", "nohash-hasher", @@ -6345,7 +6345,7 @@ dependencies = [ [[package]] name = "re_time_panel" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", "criterion", @@ -6374,7 +6374,7 @@ dependencies = [ [[package]] name = "re_tracing" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "puffin", "puffin_http", @@ -6385,7 +6385,7 @@ dependencies = [ [[package]] name = "re_tuid" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "criterion", "document-features", @@ -6398,7 +6398,7 @@ dependencies = [ [[package]] name = "re_types" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", "array-init", @@ -6440,7 +6440,7 @@ dependencies = [ [[package]] name = "re_types_builder" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", "arrow", @@ -6471,7 +6471,7 @@ dependencies = [ [[package]] name = "re_types_core" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", "arrow", @@ -6496,7 +6496,7 @@ dependencies = [ [[package]] name = "re_ui" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "eframe", "egui", @@ -6522,7 +6522,7 @@ dependencies = [ [[package]] name = "re_video" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "bit-vec", "cfg_aliases 0.2.1", @@ -6550,7 +6550,7 @@ dependencies = [ [[package]] name = "re_view" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "ahash", "arrow", @@ -6575,7 +6575,7 @@ dependencies = [ [[package]] name = "re_view_bar_chart" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "egui", "egui_plot", @@ -6593,7 +6593,7 @@ dependencies = [ [[package]] name = "re_view_dataframe" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", "egui", @@ -6616,7 +6616,7 @@ dependencies = [ [[package]] name = "re_view_graph" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "ahash", "egui", @@ -6640,7 +6640,7 @@ dependencies = [ [[package]] name = "re_view_map" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "bytemuck", "egui", @@ -6664,7 +6664,7 @@ dependencies = [ [[package]] name = "re_view_spatial" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "ahash", "anyhow", @@ -6708,7 +6708,7 @@ dependencies = [ [[package]] name = "re_view_tensor" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", "bytemuck", @@ -6732,7 +6732,7 @@ dependencies = [ [[package]] name = "re_view_text_document" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "egui", "egui_commonmark", @@ -6747,7 +6747,7 @@ dependencies = [ [[package]] name = "re_view_text_log" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "egui", "egui_extras", @@ -6767,7 +6767,7 @@ dependencies = [ [[package]] name = "re_view_time_series" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "egui", "egui_plot", @@ -6789,7 +6789,7 @@ dependencies = [ [[package]] name = "re_viewer" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "ahash", "anyhow", @@ -6867,7 +6867,7 @@ dependencies = [ [[package]] name = "re_viewer_context" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "ahash", "anyhow", @@ -6884,6 +6884,7 @@ dependencies = [ "emath", "glam", "half", + "home", "image", "indexmap 2.6.0", "itertools 0.13.0", @@ -6923,7 +6924,7 @@ dependencies = [ [[package]] name = "re_viewport" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "ahash", "egui", @@ -6946,7 +6947,7 @@ dependencies = [ [[package]] name = "re_viewport_blueprint" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "ahash", "egui", @@ -6972,7 +6973,7 @@ dependencies = [ [[package]] name = "re_web_viewer_server" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "document-features", "re_analytics", @@ -6983,7 +6984,7 @@ dependencies = [ [[package]] name = "re_ws_comms" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", "bincode", @@ -7180,7 +7181,7 @@ dependencies = [ [[package]] name = "rerun" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", "clap", @@ -7221,7 +7222,7 @@ dependencies = [ [[package]] name = "rerun-cli" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "document-features", "mimalloc", @@ -7236,7 +7237,7 @@ dependencies = [ [[package]] name = "rerun-loader-rust-file" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", "argh", @@ -7245,7 +7246,7 @@ dependencies = [ [[package]] name = "rerun_c" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "ahash", "infer", @@ -7259,7 +7260,7 @@ dependencies = [ [[package]] name = "rerun_py" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "arrow", "crossbeam", @@ -7392,7 +7393,7 @@ dependencies = [ [[package]] name = "roundtrip_annotation_context" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", "clap", @@ -7402,7 +7403,7 @@ dependencies = [ [[package]] name = "roundtrip_arrows2d" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", "clap", @@ -7412,7 +7413,7 @@ dependencies = [ [[package]] name = "roundtrip_arrows3d" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", "clap", @@ -7422,7 +7423,7 @@ dependencies = [ [[package]] name = "roundtrip_boxes2d" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", "clap", @@ -7432,7 +7433,7 @@ dependencies = [ [[package]] name = "roundtrip_boxes3d" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", "clap", @@ -7442,7 +7443,7 @@ dependencies = [ [[package]] name = "roundtrip_depth_image" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", "clap", @@ -7453,7 +7454,7 @@ dependencies = [ [[package]] name = "roundtrip_disconnected_space" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", "clap", @@ -7463,7 +7464,7 @@ dependencies = [ [[package]] name = "roundtrip_image" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", "clap", @@ -7476,7 +7477,7 @@ dependencies = [ [[package]] name = "roundtrip_line_strips2d" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", "clap", @@ -7486,7 +7487,7 @@ dependencies = [ [[package]] name = "roundtrip_line_strips3d" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", "clap", @@ -7496,7 +7497,7 @@ dependencies = [ [[package]] name = "roundtrip_pinhole" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", "clap", @@ -7506,7 +7507,7 @@ dependencies = [ [[package]] name = "roundtrip_points2d" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", "clap", @@ -7516,7 +7517,7 @@ dependencies = [ [[package]] name = "roundtrip_points3d" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", "clap", @@ -7526,7 +7527,7 @@ dependencies = [ [[package]] name = "roundtrip_segmentation_image" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", "clap", @@ -7537,7 +7538,7 @@ dependencies = [ [[package]] name = "roundtrip_tensor" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", "clap", @@ -7548,7 +7549,7 @@ dependencies = [ [[package]] name = "roundtrip_text_document" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", "clap", @@ -7558,7 +7559,7 @@ dependencies = [ [[package]] name = "roundtrip_text_log" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", "clap", @@ -7568,7 +7569,7 @@ dependencies = [ [[package]] name = "roundtrip_transform3d" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", "clap", @@ -7578,7 +7579,7 @@ dependencies = [ [[package]] name = "roundtrip_view_coordinates" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", "clap", @@ -7588,7 +7589,7 @@ dependencies = [ [[package]] name = "roundtrip_visible_time_ranges" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", "clap", @@ -7604,7 +7605,7 @@ checksum = "3cd14fd5e3b777a7422cca79358c57a8f6e3a703d9ac187448d0daf220c2407f" [[package]] name = "run_wasm" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "cargo-run-wasm", "pico-args", @@ -7996,7 +7997,7 @@ dependencies = [ [[package]] name = "shared_recording" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "rerun", ] @@ -8175,7 +8176,7 @@ dependencies = [ [[package]] name = "snippets" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "itertools 0.13.0", "ndarray", @@ -8199,7 +8200,7 @@ dependencies = [ [[package]] name = "spawn_viewer" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "rerun", ] @@ -8250,7 +8251,7 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "stdio" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "rerun", ] @@ -8427,7 +8428,7 @@ dependencies = [ [[package]] name = "template" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "rerun", ] @@ -8443,7 +8444,7 @@ dependencies = [ [[package]] name = "test_api" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", "clap", @@ -8458,7 +8459,7 @@ dependencies = [ [[package]] name = "test_data_density_graph" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", "rand", @@ -8468,7 +8469,7 @@ dependencies = [ [[package]] name = "test_image_memory" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "mimalloc", "re_format", @@ -8477,7 +8478,7 @@ dependencies = [ [[package]] name = "test_pinhole_projection" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", "clap", @@ -8488,7 +8489,7 @@ dependencies = [ [[package]] name = "test_send_columns" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "re_chunk", "rerun", @@ -8496,7 +8497,7 @@ dependencies = [ [[package]] name = "test_ui_wakeup" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", "clap", diff --git a/Cargo.toml b/Cargo.toml index 25af7569328a..eb00eb01b02a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,7 +31,7 @@ include = [ license = "MIT OR Apache-2.0" repository = "https://github.com/rerun-io/rerun" rust-version = "1.80" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" [workspace.dependencies] # When using alpha-release, always use exact version, e.g. `version = "=0.x.y-alpha.z" @@ -40,78 +40,78 @@ version = "0.21.0-alpha.1+dev" # re_log_types 0.3.0-alpha.0, NOT 0.3.0-alpha.4 even though it is newer and semver-compatible. # crates/build: -re_build_info = { path = "crates/build/re_build_info", version = "=0.21.0-alpha.1", default-features = false } -re_build_tools = { path = "crates/build/re_build_tools", version = "=0.21.0-alpha.1", default-features = false } -re_dev_tools = { path = "crates/build/re_dev_tools", version = "=0.21.0-alpha.1", default-features = false } -re_protos_builder = { path = "crates/build/re_protos_builder", version = "=0.21.0-alpha.1", default-features = false } -re_types_builder = { path = "crates/build/re_types_builder", version = "=0.21.0-alpha.1", default-features = false } +re_build_info = { path = "crates/build/re_build_info", version = "=0.22.0-alpha.1", default-features = false } +re_build_tools = { path = "crates/build/re_build_tools", version = "=0.22.0-alpha.1", default-features = false } +re_dev_tools = { path = "crates/build/re_dev_tools", version = "=0.22.0-alpha.1", default-features = false } +re_protos_builder = { path = "crates/build/re_protos_builder", version = "=0.22.0-alpha.1", default-features = false } +re_types_builder = { path = "crates/build/re_types_builder", version = "=0.22.0-alpha.1", default-features = false } # crates/store: -re_chunk = { path = "crates/store/re_chunk", version = "=0.21.0-alpha.1", default-features = false } -re_chunk_store = { path = "crates/store/re_chunk_store", version = "=0.21.0-alpha.1", default-features = false } -re_data_loader = { path = "crates/store/re_data_loader", version = "=0.21.0-alpha.1", default-features = false } -re_data_source = { path = "crates/store/re_data_source", version = "=0.21.0-alpha.1", default-features = false } -re_dataframe = { path = "crates/store/re_dataframe", version = "=0.21.0-alpha.1", default-features = false } -re_entity_db = { path = "crates/store/re_entity_db", version = "=0.21.0-alpha.1", default-features = false } -re_format_arrow = { path = "crates/store/re_format_arrow", version = "=0.21.0-alpha.1", default-features = false } -re_grpc_client = { path = "crates/store/re_grpc_client", version = "=0.21.0-alpha.1", default-features = false } -re_protos = { path = "crates/store/re_protos", version = "=0.21.0-alpha.1", default-features = false } -re_log_encoding = { path = "crates/store/re_log_encoding", version = "=0.21.0-alpha.1", default-features = false } -re_log_types = { path = "crates/store/re_log_types", version = "=0.21.0-alpha.1", default-features = false } -re_query = { path = "crates/store/re_query", version = "=0.21.0-alpha.1", default-features = false } -re_sdk_comms = { path = "crates/store/re_sdk_comms", version = "=0.21.0-alpha.1", default-features = false } -re_types = { path = "crates/store/re_types", version = "=0.21.0-alpha.1", default-features = false } -re_types_core = { path = "crates/store/re_types_core", version = "=0.21.0-alpha.1", default-features = false } -re_ws_comms = { path = "crates/store/re_ws_comms", version = "=0.21.0-alpha.1", default-features = false } +re_chunk = { path = "crates/store/re_chunk", version = "=0.22.0-alpha.1", default-features = false } +re_chunk_store = { path = "crates/store/re_chunk_store", version = "=0.22.0-alpha.1", default-features = false } +re_data_loader = { path = "crates/store/re_data_loader", version = "=0.22.0-alpha.1", default-features = false } +re_data_source = { path = "crates/store/re_data_source", version = "=0.22.0-alpha.1", default-features = false } +re_dataframe = { path = "crates/store/re_dataframe", version = "=0.22.0-alpha.1", default-features = false } +re_entity_db = { path = "crates/store/re_entity_db", version = "=0.22.0-alpha.1", default-features = false } +re_format_arrow = { path = "crates/store/re_format_arrow", version = "=0.22.0-alpha.1", default-features = false } +re_grpc_client = { path = "crates/store/re_grpc_client", version = "=0.22.0-alpha.1", default-features = false } +re_protos = { path = "crates/store/re_protos", version = "=0.22.0-alpha.1", default-features = false } +re_log_encoding = { path = "crates/store/re_log_encoding", version = "=0.22.0-alpha.1", default-features = false } +re_log_types = { path = "crates/store/re_log_types", version = "=0.22.0-alpha.1", default-features = false } +re_query = { path = "crates/store/re_query", version = "=0.22.0-alpha.1", default-features = false } +re_sdk_comms = { path = "crates/store/re_sdk_comms", version = "=0.22.0-alpha.1", default-features = false } +re_types = { path = "crates/store/re_types", version = "=0.22.0-alpha.1", default-features = false } +re_types_core = { path = "crates/store/re_types_core", version = "=0.22.0-alpha.1", default-features = false } +re_ws_comms = { path = "crates/store/re_ws_comms", version = "=0.22.0-alpha.1", default-features = false } # crates/top: -re_sdk = { path = "crates/top/re_sdk", version = "=0.21.0-alpha.1", default-features = false } -rerun = { path = "crates/top/rerun", version = "=0.21.0-alpha.1", default-features = false } -rerun_c = { path = "crates/top/rerun_c", version = "=0.21.0-alpha.1", default-features = false } -rerun-cli = { path = "crates/top/rerun-cli", version = "=0.21.0-alpha.1", default-features = false } +re_sdk = { path = "crates/top/re_sdk", version = "=0.22.0-alpha.1", default-features = false } +rerun = { path = "crates/top/rerun", version = "=0.22.0-alpha.1", default-features = false } +rerun_c = { path = "crates/top/rerun_c", version = "=0.22.0-alpha.1", default-features = false } +rerun-cli = { path = "crates/top/rerun-cli", version = "=0.22.0-alpha.1", default-features = false } # crates/utils: -re_analytics = { path = "crates/utils/re_analytics", version = "=0.21.0-alpha.1", default-features = false } -re_capabilities = { path = "crates/utils/re_capabilities", version = "=0.21.0-alpha.1", default-features = false } -re_case = { path = "crates/utils/re_case", version = "=0.21.0-alpha.1", default-features = false } -re_crash_handler = { path = "crates/utils/re_crash_handler", version = "=0.21.0-alpha.1", default-features = false } -re_error = { path = "crates/utils/re_error", version = "=0.21.0-alpha.1", default-features = false } -re_format = { path = "crates/utils/re_format", version = "=0.21.0-alpha.1", default-features = false } -re_int_histogram = { path = "crates/utils/re_int_histogram", version = "=0.21.0-alpha.1", default-features = false } -re_log = { path = "crates/utils/re_log", version = "=0.21.0-alpha.1", default-features = false } -re_memory = { path = "crates/utils/re_memory", version = "=0.21.0-alpha.1", default-features = false } -re_smart_channel = { path = "crates/utils/re_smart_channel", version = "=0.21.0-alpha.1", default-features = false } -re_string_interner = { path = "crates/utils/re_string_interner", version = "=0.21.0-alpha.1", default-features = false } -re_tracing = { path = "crates/utils/re_tracing", version = "=0.21.0-alpha.1", default-features = false } -re_tuid = { path = "crates/utils/re_tuid", version = "=0.21.0-alpha.1", default-features = false } -re_video = { path = "crates/utils/re_video", version = "=0.21.0-alpha.1", default-features = false } +re_analytics = { path = "crates/utils/re_analytics", version = "=0.22.0-alpha.1", default-features = false } +re_capabilities = { path = "crates/utils/re_capabilities", version = "=0.22.0-alpha.1", default-features = false } +re_case = { path = "crates/utils/re_case", version = "=0.22.0-alpha.1", default-features = false } +re_crash_handler = { path = "crates/utils/re_crash_handler", version = "=0.22.0-alpha.1", default-features = false } +re_error = { path = "crates/utils/re_error", version = "=0.22.0-alpha.1", default-features = false } +re_format = { path = "crates/utils/re_format", version = "=0.22.0-alpha.1", default-features = false } +re_int_histogram = { path = "crates/utils/re_int_histogram", version = "=0.22.0-alpha.1", default-features = false } +re_log = { path = "crates/utils/re_log", version = "=0.22.0-alpha.1", default-features = false } +re_memory = { path = "crates/utils/re_memory", version = "=0.22.0-alpha.1", default-features = false } +re_smart_channel = { path = "crates/utils/re_smart_channel", version = "=0.22.0-alpha.1", default-features = false } +re_string_interner = { path = "crates/utils/re_string_interner", version = "=0.22.0-alpha.1", default-features = false } +re_tracing = { path = "crates/utils/re_tracing", version = "=0.22.0-alpha.1", default-features = false } +re_tuid = { path = "crates/utils/re_tuid", version = "=0.22.0-alpha.1", default-features = false } +re_video = { path = "crates/utils/re_video", version = "=0.22.0-alpha.1", default-features = false } # crates/viewer: -re_blueprint_tree = { path = "crates/viewer/re_blueprint_tree", version = "=0.21.0-alpha.1", default-features = false } -re_component_ui = { path = "crates/viewer/re_component_ui", version = "=0.21.0-alpha.1", default-features = false } -re_context_menu = { path = "crates/viewer/re_context_menu", version = "=0.21.0-alpha.1", default-features = false } -re_data_ui = { path = "crates/viewer/re_data_ui", version = "=0.21.0-alpha.1", default-features = false } -re_chunk_store_ui = { path = "crates/viewer/re_chunk_store_ui", version = "=0.21.0-alpha.1", default-features = false } -re_renderer = { path = "crates/viewer/re_renderer", version = "=0.21.0-alpha.1", default-features = false } -re_renderer_examples = { path = "crates/viewer/re_renderer_examples", version = "=0.21.0-alpha.1", default-features = false } -re_selection_panel = { path = "crates/viewer/re_selection_panel", version = "=0.21.0-alpha.1", default-features = false } -re_view = { path = "crates/viewer/re_view", version = "=0.21.0-alpha.1", default-features = false } -re_view_bar_chart = { path = "crates/viewer/re_view_bar_chart", version = "=0.21.0-alpha.1", default-features = false } -re_view_spatial = { path = "crates/viewer/re_view_spatial", version = "=0.21.0-alpha.1", default-features = false } -re_view_dataframe = { path = "crates/viewer/re_view_dataframe", version = "=0.21.0-alpha.1", default-features = false } -re_view_graph = { path = "crates/viewer/re_view_graph", version = "=0.21.0-alpha.1", default-features = false } -re_view_map = { path = "crates/viewer/re_view_map", version = "=0.21.0-alpha.1", default-features = false } -re_view_tensor = { path = "crates/viewer/re_view_tensor", version = "=0.21.0-alpha.1", default-features = false } -re_view_text_document = { path = "crates/viewer/re_view_text_document", version = "=0.21.0-alpha.1", default-features = false } -re_view_text_log = { path = "crates/viewer/re_view_text_log", version = "=0.21.0-alpha.1", default-features = false } -re_view_time_series = { path = "crates/viewer/re_view_time_series", version = "=0.21.0-alpha.1", default-features = false } -re_time_panel = { path = "crates/viewer/re_time_panel", version = "=0.21.0-alpha.1", default-features = false } -re_ui = { path = "crates/viewer/re_ui", version = "=0.21.0-alpha.1", default-features = false } -re_viewer = { path = "crates/viewer/re_viewer", version = "=0.21.0-alpha.1", default-features = false } -re_viewer_context = { path = "crates/viewer/re_viewer_context", version = "=0.21.0-alpha.1", default-features = false } -re_viewport = { path = "crates/viewer/re_viewport", version = "=0.21.0-alpha.1", default-features = false } -re_viewport_blueprint = { path = "crates/viewer/re_viewport_blueprint", version = "=0.21.0-alpha.1", default-features = false } -re_web_viewer_server = { path = "crates/viewer/re_web_viewer_server", version = "=0.21.0-alpha.1", default-features = false } +re_blueprint_tree = { path = "crates/viewer/re_blueprint_tree", version = "=0.22.0-alpha.1", default-features = false } +re_component_ui = { path = "crates/viewer/re_component_ui", version = "=0.22.0-alpha.1", default-features = false } +re_context_menu = { path = "crates/viewer/re_context_menu", version = "=0.22.0-alpha.1", default-features = false } +re_data_ui = { path = "crates/viewer/re_data_ui", version = "=0.22.0-alpha.1", default-features = false } +re_chunk_store_ui = { path = "crates/viewer/re_chunk_store_ui", version = "=0.22.0-alpha.1", default-features = false } +re_renderer = { path = "crates/viewer/re_renderer", version = "=0.22.0-alpha.1", default-features = false } +re_renderer_examples = { path = "crates/viewer/re_renderer_examples", version = "=0.22.0-alpha.1", default-features = false } +re_selection_panel = { path = "crates/viewer/re_selection_panel", version = "=0.22.0-alpha.1", default-features = false } +re_view = { path = "crates/viewer/re_view", version = "=0.22.0-alpha.1", default-features = false } +re_view_bar_chart = { path = "crates/viewer/re_view_bar_chart", version = "=0.22.0-alpha.1", default-features = false } +re_view_spatial = { path = "crates/viewer/re_view_spatial", version = "=0.22.0-alpha.1", default-features = false } +re_view_dataframe = { path = "crates/viewer/re_view_dataframe", version = "=0.22.0-alpha.1", default-features = false } +re_view_graph = { path = "crates/viewer/re_view_graph", version = "=0.22.0-alpha.1", default-features = false } +re_view_map = { path = "crates/viewer/re_view_map", version = "=0.22.0-alpha.1", default-features = false } +re_view_tensor = { path = "crates/viewer/re_view_tensor", version = "=0.22.0-alpha.1", default-features = false } +re_view_text_document = { path = "crates/viewer/re_view_text_document", version = "=0.22.0-alpha.1", default-features = false } +re_view_text_log = { path = "crates/viewer/re_view_text_log", version = "=0.22.0-alpha.1", default-features = false } +re_view_time_series = { path = "crates/viewer/re_view_time_series", version = "=0.22.0-alpha.1", default-features = false } +re_time_panel = { path = "crates/viewer/re_time_panel", version = "=0.22.0-alpha.1", default-features = false } +re_ui = { path = "crates/viewer/re_ui", version = "=0.22.0-alpha.1", default-features = false } +re_viewer = { path = "crates/viewer/re_viewer", version = "=0.22.0-alpha.1", default-features = false } +re_viewer_context = { path = "crates/viewer/re_viewer_context", version = "=0.22.0-alpha.1", default-features = false } +re_viewport = { path = "crates/viewer/re_viewport", version = "=0.22.0-alpha.1", default-features = false } +re_viewport_blueprint = { path = "crates/viewer/re_viewport_blueprint", version = "=0.22.0-alpha.1", default-features = false } +re_web_viewer_server = { path = "crates/viewer/re_web_viewer_server", version = "=0.22.0-alpha.1", default-features = false } # Rerun crates in other repos: ewebsock = "0.8.0" @@ -193,6 +193,7 @@ glob = "0.3" gltf = "1.1" half = "2.3.1" hexasphere = "14.1.0" +home = "=0.5.9" image = { version = "0.25", default-features = false } indent = "0.1" indexmap = "2.1" # Version chosen to align with other dependencies diff --git a/crates/build/re_types_builder/src/codegen/docs/snippets_ref.rs b/crates/build/re_types_builder/src/codegen/docs/snippets_ref.rs index 47fe4e3cfeac..322785041e9c 100644 --- a/crates/build/re_types_builder/src/codegen/docs/snippets_ref.rs +++ b/crates/build/re_types_builder/src/codegen/docs/snippets_ref.rs @@ -631,9 +631,8 @@ fn is_speculative(any_name: &str) -> anyhow::Result { let minor: u32 = env!("CARGO_PKG_VERSION_MINOR") .parse() .context("couldn't parse minor crate version")?; - let pre = env!("CARGO_PKG_VERSION_PRE"); - minor < 21 || !pre.is_empty() + minor < 21 }; const RELEASED_IN_0_21: &[&str] = &[ diff --git a/crates/store/re_types/definitions/rerun/archetypes/ellipsoids3d.fbs b/crates/store/re_types/definitions/rerun/archetypes/ellipsoids3d.fbs index 0fb824dc7017..469ff7009186 100644 --- a/crates/store/re_types/definitions/rerun/archetypes/ellipsoids3d.fbs +++ b/crates/store/re_types/definitions/rerun/archetypes/ellipsoids3d.fbs @@ -12,7 +12,7 @@ namespace rerun.archetypes; /// Some of its component are repeated here for convenience. /// If there's more instance poses than half sizes, the last half size will be repeated for the remaining poses. /// -/// \example archetypes/ellipsoids3d_simple !api title="Covariance ellipsoid" image="https://static.rerun.io/elliopsoid3d_simple/bd5d46e61b80ae44792b52ee07d750a7137002ea/1200w.png" +/// \example archetypes/ellipsoids3d_simple title="Covariance ellipsoid" image="https://static.rerun.io/elliopsoid3d_simple/bd5d46e61b80ae44792b52ee07d750a7137002ea/1200w.png" table Ellipsoids3D ( "attr.rust.derive": "PartialEq", "attr.rust.new_pub_crate", diff --git a/crates/store/re_types/definitions/rerun/archetypes/graph_edges.fbs b/crates/store/re_types/definitions/rerun/archetypes/graph_edges.fbs index 337787158f71..c85a4e58e4bb 100644 --- a/crates/store/re_types/definitions/rerun/archetypes/graph_edges.fbs +++ b/crates/store/re_types/definitions/rerun/archetypes/graph_edges.fbs @@ -10,10 +10,8 @@ namespace rerun.archetypes; /// \example archetypes/graph_directed title="Simple directed graph" image="https://static.rerun.io/graph_directed/ca29a37b65e1e0b6482251dce401982a0bc568fa/1200w.png" table GraphEdges ( "attr.docs.category": "Graph", - "attr.docs.unreleased", "attr.docs.view_types": "GraphView", - "attr.rust.derive": "PartialEq, Eq", - "attr.rerun.experimental" + "attr.rust.derive": "PartialEq, Eq" ) { // --- Required --- diff --git a/crates/store/re_types/definitions/rerun/archetypes/graph_nodes.fbs b/crates/store/re_types/definitions/rerun/archetypes/graph_nodes.fbs index 142a88dd2444..d169b97bd25b 100644 --- a/crates/store/re_types/definitions/rerun/archetypes/graph_nodes.fbs +++ b/crates/store/re_types/definitions/rerun/archetypes/graph_nodes.fbs @@ -8,10 +8,8 @@ namespace rerun.archetypes; /// \example archetypes/graph_directed title="Simple directed graph" image="https://static.rerun.io/graph_directed/ca29a37b65e1e0b6482251dce401982a0bc568fa/1200w.png" table GraphNodes ( "attr.docs.category": "Graph", - "attr.docs.unreleased", "attr.docs.view_types": "GraphView", - "attr.rust.derive": "PartialEq", - "attr.rerun.experimental" + "attr.rust.derive": "PartialEq" ) { // --- Required --- diff --git a/crates/store/re_types/definitions/rerun/blueprint/archetypes/near_clip_plane.fbs b/crates/store/re_types/definitions/rerun/blueprint/archetypes/near_clip_plane.fbs index a157d67a2982..9875dfde1004 100644 --- a/crates/store/re_types/definitions/rerun/blueprint/archetypes/near_clip_plane.fbs +++ b/crates/store/re_types/definitions/rerun/blueprint/archetypes/near_clip_plane.fbs @@ -2,7 +2,6 @@ namespace rerun.blueprint.archetypes; /// Controls the distance to the near clip plane in 3D scene units. table NearClipPlane ( - "attr.docs.unreleased", "attr.rerun.scope": "blueprint", "attr.rust.derive": "Copy" ) { diff --git a/crates/store/re_types/definitions/rerun/blueprint/components/near_clip_plane.fbs b/crates/store/re_types/definitions/rerun/blueprint/components/near_clip_plane.fbs index 200fc64ef33b..aa7aa3582d1f 100644 --- a/crates/store/re_types/definitions/rerun/blueprint/components/near_clip_plane.fbs +++ b/crates/store/re_types/definitions/rerun/blueprint/components/near_clip_plane.fbs @@ -6,8 +6,7 @@ namespace rerun.blueprint.components; struct NearClipPlane ( "attr.rerun.scope": "blueprint", "attr.rust.derive": "Copy, PartialEq, bytemuck::Pod, bytemuck::Zeroable", - "attr.rust.repr": "transparent", - "attr.docs.unreleased" + "attr.rust.repr": "transparent" ) { /// Distance to the near clip plane in 3D scene units. near_clip_plane: rerun.datatypes.Float32 (order: 100); diff --git a/crates/store/re_types/definitions/rerun/blueprint/views/graph.fbs b/crates/store/re_types/definitions/rerun/blueprint/views/graph.fbs index 848ad4f3255a..7710b0856c02 100644 --- a/crates/store/re_types/definitions/rerun/blueprint/views/graph.fbs +++ b/crates/store/re_types/definitions/rerun/blueprint/views/graph.fbs @@ -4,8 +4,7 @@ namespace rerun.blueprint.views; /// /// \example views/graph title="Use a blueprint to create a graph view." image="https://static.rerun.io/graph_lattice/f9169da9c3f35b7260c9d74cd5be5fe710aec6a8/1200w.png" table GraphView ( - "attr.rerun.view_identifier": "Graph", - "attr.docs.unreleased" + "attr.rerun.view_identifier": "Graph" ) { /// Everything within these bounds is guaranteed to be visible. /// diff --git a/crates/store/re_types/definitions/rerun/components/graph_edge.fbs b/crates/store/re_types/definitions/rerun/components/graph_edge.fbs index 1f97a2e6c506..435dee9efa5a 100644 --- a/crates/store/re_types/definitions/rerun/components/graph_edge.fbs +++ b/crates/store/re_types/definitions/rerun/components/graph_edge.fbs @@ -4,7 +4,6 @@ namespace rerun.components; /// An edge in a graph connecting two nodes. table GraphEdge ( - "attr.docs.unreleased", "attr.rust.derive": "Default, PartialEq, Eq, PartialOrd, Ord", "attr.rust.repr": "transparent" ) { diff --git a/crates/store/re_types/definitions/rerun/components/graph_node.fbs b/crates/store/re_types/definitions/rerun/components/graph_node.fbs index 7867665a380a..3af3d6f2f185 100644 --- a/crates/store/re_types/definitions/rerun/components/graph_node.fbs +++ b/crates/store/re_types/definitions/rerun/components/graph_node.fbs @@ -4,7 +4,6 @@ namespace rerun.components; /// A string-based ID representing a node in a graph. table GraphNode ( - "attr.docs.unreleased", "attr.python.aliases": "str", "attr.python.array_aliases": "str, Sequence[str]", "attr.rust.derive": "Default, PartialEq, Eq, PartialOrd, Ord, Hash", diff --git a/crates/store/re_types/definitions/rerun/components/graph_type.fbs b/crates/store/re_types/definitions/rerun/components/graph_type.fbs index 283e3a2b93b4..1348c6b20479 100644 --- a/crates/store/re_types/definitions/rerun/components/graph_type.fbs +++ b/crates/store/re_types/definitions/rerun/components/graph_type.fbs @@ -4,7 +4,6 @@ namespace rerun.components; /// Specifies if a graph has directed or undirected edges. enum GraphType: ubyte ( - "attr.docs.unreleased", "attr.rust.derive": "Default, PartialEq, Eq" ) { /// Invalid value. Won't show up in generated types. diff --git a/crates/store/re_types/definitions/rerun/components/plane3d.fbs b/crates/store/re_types/definitions/rerun/components/plane3d.fbs index e60aa4efdf58..21c8b139d1c4 100644 --- a/crates/store/re_types/definitions/rerun/components/plane3d.fbs +++ b/crates/store/re_types/definitions/rerun/components/plane3d.fbs @@ -10,7 +10,6 @@ namespace rerun.components; /// datastore as provided, when used in the Viewer, planes will always be normalized. /// I.e. the plane with xyz = (2, 0, 0), d = 1 is equivalent to xyz = (1, 0, 0), d = 0.5 struct Plane3D ( - "attr.docs.unreleased", "attr.rust.derive": "Copy, PartialEq, bytemuck::Pod, bytemuck::Zeroable", "attr.rust.repr": "transparent" ) { diff --git a/crates/store/re_types/definitions/rerun/components/recording_uri.fbs b/crates/store/re_types/definitions/rerun/components/recording_uri.fbs index e27204f5251d..22966e126eb4 100644 --- a/crates/store/re_types/definitions/rerun/components/recording_uri.fbs +++ b/crates/store/re_types/definitions/rerun/components/recording_uri.fbs @@ -4,8 +4,7 @@ namespace rerun.components; /// A recording URI (Uniform Resource Identifier). table RecordingUri ( - "attr.rust.derive": "PartialEq, Eq, PartialOrd, Ord, Hash", - "attr.docs.unreleased" + "attr.rust.derive": "PartialEq, Eq, PartialOrd, Ord, Hash" ) { recording_uri: rerun.datatypes.Utf8 (order: 100); } diff --git a/crates/store/re_types/definitions/rerun/datatypes/plane3d.fbs b/crates/store/re_types/definitions/rerun/datatypes/plane3d.fbs index a490f8450481..acfeb4741ce8 100644 --- a/crates/store/re_types/definitions/rerun/datatypes/plane3d.fbs +++ b/crates/store/re_types/definitions/rerun/datatypes/plane3d.fbs @@ -10,7 +10,6 @@ namespace rerun.datatypes; /// datastore as provided, when used in the Viewer, planes will always be normalized. /// I.e. the plane with xyz = (2, 0, 0), d = 1 is equivalent to xyz = (1, 0, 0), d = 0.5 struct Plane3D ( - "attr.docs.unreleased", "attr.arrow.transparent", "attr.python.array_aliases": "npt.NDArray[Any], npt.ArrayLike, Sequence[Sequence[float]]", "attr.rust.derive": "Copy, PartialEq, PartialOrd, bytemuck::Pod, bytemuck::Zeroable", diff --git a/crates/store/re_types/definitions/rerun/datatypes/utf8_pair.fbs b/crates/store/re_types/definitions/rerun/datatypes/utf8_pair.fbs index 9acbb85a5052..051722a1e200 100644 --- a/crates/store/re_types/definitions/rerun/datatypes/utf8_pair.fbs +++ b/crates/store/re_types/definitions/rerun/datatypes/utf8_pair.fbs @@ -2,7 +2,6 @@ namespace rerun.datatypes; /// Stores a tuple of UTF-8 strings. table Utf8Pair ( - "attr.docs.unreleased", "attr.python.aliases": "Tuple[datatypes.Utf8Like, datatypes.Utf8Like]", "attr.python.array_aliases": "npt.NDArray[np.str_]", "attr.rust.derive": "Default, PartialEq, Eq, PartialOrd, Ord" diff --git a/crates/store/re_types/src/archetypes/ellipsoids3d.rs b/crates/store/re_types/src/archetypes/ellipsoids3d.rs index bc6ee14a53f6..034fbb9f6047 100644 --- a/crates/store/re_types/src/archetypes/ellipsoids3d.rs +++ b/crates/store/re_types/src/archetypes/ellipsoids3d.rs @@ -27,6 +27,58 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; /// Note that orienting and placing the ellipsoids/spheres is handled via `[archetypes.InstancePoses3D]`. /// Some of its component are repeated here for convenience. /// If there's more instance poses than half sizes, the last half size will be repeated for the remaining poses. +/// +/// ## Example +/// +/// ### Covariance ellipsoid +/// ```ignore +/// use rand::distributions::Distribution; +/// +/// fn main() -> Result<(), Box> { +/// let rec = rerun::RecordingStreamBuilder::new("rerun_example_ellipsoid_simple").spawn()?; +/// +/// let sigmas: [f32; 3] = [5., 3., 1.]; +/// +/// let mut rng = rand::thread_rng(); +/// let normal = rand_distr::Normal::new(0.0, 1.0)?; +/// +/// rec.log( +/// "points", +/// &rerun::Points3D::new((0..50_000).map(|_| { +/// ( +/// sigmas[0] * normal.sample(&mut rng), +/// sigmas[1] * normal.sample(&mut rng), +/// sigmas[2] * normal.sample(&mut rng), +/// ) +/// })) +/// .with_radii([0.02]) +/// .with_colors([rerun::Color::from_rgb(188, 77, 185)]), +/// )?; +/// +/// rec.log( +/// "ellipsoid", +/// &rerun::Ellipsoids3D::from_centers_and_half_sizes( +/// [(0.0, 0.0, 0.0), (0.0, 0.0, 0.0)], +/// [sigmas, [sigmas[0] * 3., sigmas[1] * 3., sigmas[2] * 3.]], +/// ) +/// .with_colors([ +/// rerun::Color::from_rgb(255, 255, 0), +/// rerun::Color::from_rgb(64, 64, 0), +/// ]), +/// )?; +/// +/// Ok(()) +/// } +/// ``` +///
+/// +/// +/// +/// +/// +/// +/// +///
#[derive(Clone, Debug, PartialEq)] pub struct Ellipsoids3D { /// For each ellipsoid, half of its size on its three axes. diff --git a/crates/store/re_types/src/archetypes/graph_edges.rs b/crates/store/re_types/src/archetypes/graph_edges.rs index d30dfea19a76..19fa08c8c526 100644 --- a/crates/store/re_types/src/archetypes/graph_edges.rs +++ b/crates/store/re_types/src/archetypes/graph_edges.rs @@ -22,8 +22,6 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; /// /// By default, edges are undirected. /// -/// ⚠️ **This type is experimental and may be removed in future versions** -/// /// ## Example /// /// ### Simple directed graph diff --git a/crates/store/re_types/src/archetypes/graph_nodes.rs b/crates/store/re_types/src/archetypes/graph_nodes.rs index 3f3e707e185f..5931330051f3 100644 --- a/crates/store/re_types/src/archetypes/graph_nodes.rs +++ b/crates/store/re_types/src/archetypes/graph_nodes.rs @@ -20,8 +20,6 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; /// **Archetype**: A list of nodes in a graph with optional labels, colors, etc. /// -/// ⚠️ **This type is experimental and may be removed in future versions** -/// /// ## Example /// /// ### Simple directed graph diff --git a/crates/store/re_types/src/reflection/mod.rs b/crates/store/re_types/src/reflection/mod.rs index 05839fe7c80e..cd1537ad937b 100644 --- a/crates/store/re_types/src/reflection/mod.rs +++ b/crates/store/re_types/src/reflection/mod.rs @@ -1413,11 +1413,11 @@ fn generate_archetype_reflection() -> ArchetypeReflectionMap { fields: vec![ ArchetypeFieldReflection { name : "edges", display_name : "Edges", component_name : "rerun.components.GraphEdge".into(), docstring_md : - "A list of node tuples.\n\n⚠\u{fe0f} **This type is experimental and may be removed in future versions**", - is_required : true, }, ArchetypeFieldReflection { name : - "graph_type", display_name : "Graph type", component_name : - "rerun.components.GraphType".into(), docstring_md : - "Specifies if the graph is directed or undirected.\n\nIf no [`components.GraphType`](https://rerun.io/docs/reference/types/components/graph_type?speculative-link) is provided, the graph is assumed to be undirected.\n\n⚠\u{fe0f} **This type is experimental and may be removed in future versions**", + "A list of node tuples.", is_required : true, }, + ArchetypeFieldReflection { name : "graph_type", display_name : + "Graph type", component_name : "rerun.components.GraphType".into(), + docstring_md : + "Specifies if the graph is directed or undirected.\n\nIf no [`components.GraphType`](https://rerun.io/docs/reference/types/components/graph_type) is provided, the graph is assumed to be undirected.", is_required : false, }, ], }, @@ -1431,29 +1431,24 @@ fn generate_archetype_reflection() -> ArchetypeReflectionMap { fields: vec![ ArchetypeFieldReflection { name : "node_ids", display_name : "Node ids", component_name : "rerun.components.GraphNode".into(), - docstring_md : - "A list of node IDs.\n\n⚠\u{fe0f} **This type is experimental and may be removed in future versions**", - is_required : true, }, ArchetypeFieldReflection { name : "positions", - display_name : "Positions", component_name : - "rerun.components.Position2D".into(), docstring_md : - "Optional center positions of the nodes.\n\n⚠\u{fe0f} **This type is experimental and may be removed in future versions**", - is_required : false, }, ArchetypeFieldReflection { name : "colors", - display_name : "Colors", component_name : "rerun.components.Color" - .into(), docstring_md : - "Optional colors for the boxes.\n\n⚠\u{fe0f} **This type is experimental and may be removed in future versions**", - is_required : false, }, ArchetypeFieldReflection { name : "labels", - display_name : "Labels", component_name : "rerun.components.Text" - .into(), docstring_md : - "Optional text labels for the node.\n\n⚠\u{fe0f} **This type is experimental and may be removed in future versions**", - is_required : false, }, ArchetypeFieldReflection { name : - "show_labels", display_name : "Show labels", component_name : + docstring_md : "A list of node IDs.", is_required : true, }, + ArchetypeFieldReflection { name : "positions", display_name : + "Positions", component_name : "rerun.components.Position2D".into(), + docstring_md : "Optional center positions of the nodes.", is_required + : false, }, ArchetypeFieldReflection { name : "colors", display_name + : "Colors", component_name : "rerun.components.Color".into(), + docstring_md : "Optional colors for the boxes.", is_required : false, + }, ArchetypeFieldReflection { name : "labels", display_name : + "Labels", component_name : "rerun.components.Text".into(), + docstring_md : "Optional text labels for the node.", is_required : + false, }, ArchetypeFieldReflection { name : "show_labels", + display_name : "Show labels", component_name : "rerun.components.ShowLabels".into(), docstring_md : - "Optional choice of whether the text labels should be shown by default.\n\n⚠\u{fe0f} **This type is experimental and may be removed in future versions**", + "Optional choice of whether the text labels should be shown by default.", is_required : false, }, ArchetypeFieldReflection { name : "radii", display_name : "Radii", component_name : "rerun.components.Radius" - .into(), docstring_md : - "Optional radii for nodes.\n\n⚠\u{fe0f} **This type is experimental and may be removed in future versions**", - is_required : false, }, + .into(), docstring_md : "Optional radii for nodes.", is_required : + false, }, ], }, ), diff --git a/crates/utils/re_capabilities/README.md b/crates/utils/re_capabilities/README.md index c61326593afe..0388f986f3b5 100644 --- a/crates/utils/re_capabilities/README.md +++ b/crates/utils/re_capabilities/README.md @@ -3,7 +3,7 @@ Part of the [`rerun`](https://github.com/rerun-io/rerun) family of crates. [![Latest version](https://img.shields.io/crates/v/re_capabilities.svg)](https://crates.io/crates/re_capabilitiescrates/utils/) -[![Documentation](https://docs.rs/re_capabilities/badge.svg?speculative-link)](https://docs.rs/re_capabilities?speculative-link) +[![Documentation](https://docs.rs/re_capabilities/badge.svg)](https://docs.rs/re_capabilities) ![MIT](https://img.shields.io/badge/license-MIT-blue.svg) ![Apache](https://img.shields.io/badge/license-Apache-blue.svg) diff --git a/crates/viewer/re_view/README.md b/crates/viewer/re_view/README.md index 54410b016536..4c7f372db337 100644 --- a/crates/viewer/re_view/README.md +++ b/crates/viewer/re_view/README.md @@ -3,7 +3,7 @@ Part of the [`rerun`](https://github.com/rerun-io/rerun) family of crates. [![Latest version](https://img.shields.io/crates/v/re_view.svg)](https://crates.io/crates/re_view) -[![Documentation](https://docs.rs/re_view/badge.svg?speculative-link)](https://docs.rs/re_view?speculative-link) +[![Documentation](https://docs.rs/re_view/badge.svg)](https://docs.rs/re_view) ![MIT](https://img.shields.io/badge/license-MIT-blue.svg) ![Apache](https://img.shields.io/badge/license-Apache-blue.svg) diff --git a/crates/viewer/re_view_bar_chart/README.md b/crates/viewer/re_view_bar_chart/README.md index 524f0772e339..b3fc22dc9785 100644 --- a/crates/viewer/re_view_bar_chart/README.md +++ b/crates/viewer/re_view_bar_chart/README.md @@ -3,7 +3,7 @@ Part of the [`rerun`](https://github.com/rerun-io/rerun) family of crates. [![Latest version](https://img.shields.io/crates/v/re_view_bar_chart.svg)](https://crates.io/crates/re_view_bar_chart) -[![Documentation](https://docs.rs/re_view_bar_chart/badge.svg??speculative-link)](https://docs.rs/re_view_bar_chart?speculative-link) +[![Documentation](https://docs.rs/re_view_bar_chart/badge.svg?)](https://docs.rs/re_view_bar_chart) ![MIT](https://img.shields.io/badge/license-MIT-blue.svg) ![Apache](https://img.shields.io/badge/license-Apache-blue.svg) diff --git a/crates/viewer/re_view_dataframe/README.md b/crates/viewer/re_view_dataframe/README.md index 23fc1c7eee2f..f08ed1966a56 100644 --- a/crates/viewer/re_view_dataframe/README.md +++ b/crates/viewer/re_view_dataframe/README.md @@ -3,7 +3,7 @@ Part of the [`rerun`](https://github.com/rerun-io/rerun) family of crates. [![Latest version](https://img.shields.io/crates/v/re_view_dataframe.svg)](https://crates.io/crates/re_view_dataframe) -[![Documentation](https://docs.rs/re_view_dataframe/badge.svg?speculative-link)](https://docs.rs/re_view_dataframe?speculative-link) +[![Documentation](https://docs.rs/re_view_dataframe/badge.svg)](https://docs.rs/re_view_dataframe) ![MIT](https://img.shields.io/badge/license-MIT-blue.svg) ![Apache](https://img.shields.io/badge/license-Apache-blue.svg) diff --git a/crates/viewer/re_view_graph/README.md b/crates/viewer/re_view_graph/README.md index 3a106e7ad8c3..b64b99770608 100644 --- a/crates/viewer/re_view_graph/README.md +++ b/crates/viewer/re_view_graph/README.md @@ -1,9 +1,9 @@ # re_view_graph -Part of the [`rerun`](https://github.com/rerun-io/rerun?speculative-link) family of crates. +Part of the [`rerun`](https://github.com/rerun-io/rerun) family of crates. -[![Latest version](https://img.shields.io/crates/v/re_view_graph.svg)](https://crates.io/crates/re_view_graph?speculative-link) -[![Documentation](https://docs.rs/re_view_graph/badge.svg)](https://docs.rs/re_view_graph?speculative-link) +[![Latest version](https://img.shields.io/crates/v/re_view_graph.svg)](https://crates.io/crates/re_view_graph) +[![Documentation](https://docs.rs/re_view_graph/badge.svg)](https://docs.rs/re_view_graph) ![MIT](https://img.shields.io/badge/license-MIT-blue.svg) ![Apache](https://img.shields.io/badge/license-Apache-blue.svg) diff --git a/crates/viewer/re_view_map/README.md b/crates/viewer/re_view_map/README.md index 5555ab0cf427..e4f2338ed605 100644 --- a/crates/viewer/re_view_map/README.md +++ b/crates/viewer/re_view_map/README.md @@ -2,8 +2,8 @@ Part of the [`rerun`](https://github.com/rerun-io/rerun) family of crates. -[![Latest version](https://img.shields.io/crates/v/re_view_map.svg)](https://crates.io/crates/re_view_spatial?speculative-link) -[![Documentation](https://docs.rs/re_view_map/badge.svg)](https://docs.rs/re_view_spatial?speculative-link) +[![Latest version](https://img.shields.io/crates/v/re_view_map.svg)](https://crates.io/crates/re_view_spatial) +[![Documentation](https://docs.rs/re_view_map/badge.svg)](https://docs.rs/re_view_spatial) ![MIT](https://img.shields.io/badge/license-MIT-blue.svg) ![Apache](https://img.shields.io/badge/license-Apache-blue.svg) diff --git a/crates/viewer/re_view_spatial/README.md b/crates/viewer/re_view_spatial/README.md index 950c5eb13548..3a23de917b1e 100644 --- a/crates/viewer/re_view_spatial/README.md +++ b/crates/viewer/re_view_spatial/README.md @@ -2,8 +2,8 @@ Part of the [`rerun`](https://github.com/rerun-io/rerun) family of crates. -[![Latest version](https://img.shields.io/crates/v/re_view_spatial.svg)](https://crates.io/crates/re_view_spatial?speculative-link) -[![Documentation](https://docs.rs/re_view_spatial/badge.svg)](https://docs.rs/re_view_spatial?speculative-link) +[![Latest version](https://img.shields.io/crates/v/re_view_spatial.svg)](https://crates.io/crates/re_view_spatial) +[![Documentation](https://docs.rs/re_view_spatial/badge.svg)](https://docs.rs/re_view_spatial) ![MIT](https://img.shields.io/badge/license-MIT-blue.svg) ![Apache](https://img.shields.io/badge/license-Apache-blue.svg) diff --git a/crates/viewer/re_view_tensor/README.md b/crates/viewer/re_view_tensor/README.md index bd8bab191ee3..c0a325259122 100644 --- a/crates/viewer/re_view_tensor/README.md +++ b/crates/viewer/re_view_tensor/README.md @@ -2,8 +2,8 @@ Part of the [`rerun`](https://github.com/rerun-io/rerun) family of crates. -[![Latest version](https://img.shields.io/crates/v/re_view_tensor.svg)](https://crates.io/crates/re_view_tensor?speculative-link) -[![Documentation](https://docs.rs/re_view_tensor/badge.svg)](https://docs.rs/re_view_tensor?speculative-link) +[![Latest version](https://img.shields.io/crates/v/re_view_tensor.svg)](https://crates.io/crates/re_view_tensor) +[![Documentation](https://docs.rs/re_view_tensor/badge.svg)](https://docs.rs/re_view_tensor) ![MIT](https://img.shields.io/badge/license-MIT-blue.svg) ![Apache](https://img.shields.io/badge/license-Apache-blue.svg) diff --git a/crates/viewer/re_view_text_document/README.md b/crates/viewer/re_view_text_document/README.md index 28580760e6cd..bc8b92289567 100644 --- a/crates/viewer/re_view_text_document/README.md +++ b/crates/viewer/re_view_text_document/README.md @@ -2,8 +2,8 @@ Part of the [`rerun`](https://github.com/rerun-io/rerun) family of crates. -[![Latest version](https://img.shields.io/crates/v/re_view_text_document.svg)](https://crates.io/crates/re_view_text_document?speculative-link) -[![Documentation](https://docs.rs/re_view_text_document/badge.svg)](https://docs.rs/re_view_text_document?speculative-link) +[![Latest version](https://img.shields.io/crates/v/re_view_text_document.svg)](https://crates.io/crates/re_view_text_document) +[![Documentation](https://docs.rs/re_view_text_document/badge.svg)](https://docs.rs/re_view_text_document) ![MIT](https://img.shields.io/badge/license-MIT-blue.svg) ![Apache](https://img.shields.io/badge/license-Apache-blue.svg) diff --git a/crates/viewer/re_view_text_log/README.md b/crates/viewer/re_view_text_log/README.md index 8ae9b824d012..1d0ff0848bf9 100644 --- a/crates/viewer/re_view_text_log/README.md +++ b/crates/viewer/re_view_text_log/README.md @@ -2,8 +2,8 @@ Part of the [`rerun`](https://github.com/rerun-io/rerun) family of crates. -[![Latest version](https://img.shields.io/crates/v/re_view_text_log.svg)](https://crates.io/crates/re_view_text_log?speculative-link) -[![Documentation](https://docs.rs/re_view_text_log/badge.svg)](https://docs.rs/re_view_text_log?speculative-link) +[![Latest version](https://img.shields.io/crates/v/re_view_text_log.svg)](https://crates.io/crates/re_view_text_log) +[![Documentation](https://docs.rs/re_view_text_log/badge.svg)](https://docs.rs/re_view_text_log) ![MIT](https://img.shields.io/badge/license-MIT-blue.svg) ![Apache](https://img.shields.io/badge/license-Apache-blue.svg) diff --git a/crates/viewer/re_view_time_series/README.md b/crates/viewer/re_view_time_series/README.md index 2c6c7fb5ab32..fc2556bd111d 100644 --- a/crates/viewer/re_view_time_series/README.md +++ b/crates/viewer/re_view_time_series/README.md @@ -2,8 +2,8 @@ Part of the [`rerun`](https://github.com/rerun-io/rerun) family of crates. -[![Latest version](https://img.shields.io/crates/v/re_view_bar_chart.svg)](https://crates.io/crates/re_view_bar_chart?speculative-link) -[![Documentation](https://docs.rs/re_view_bar_chart/badge.svg)](https://docs.rs/re_view_bar_chart?speculative-link) +[![Latest version](https://img.shields.io/crates/v/re_view_bar_chart.svg)](https://crates.io/crates/re_view_bar_chart) +[![Documentation](https://docs.rs/re_view_bar_chart/badge.svg)](https://docs.rs/re_view_bar_chart) ![MIT](https://img.shields.io/badge/license-MIT-blue.svg) ![Apache](https://img.shields.io/badge/license-Apache-blue.svg) diff --git a/crates/viewer/re_viewer/README.md b/crates/viewer/re_viewer/README.md index adf3ef575924..10c648321f03 100644 --- a/crates/viewer/re_viewer/README.md +++ b/crates/viewer/re_viewer/README.md @@ -2,8 +2,8 @@ Part of the [`rerun`](https://github.com/rerun-io/rerun) family of crates. -[![Latest version](https://img.shields.io/crates/v/re_viewer.svg)](https://crates.io/crates/viewer/re_viewer?speculative-link) -[![Documentation](https://docs.rs/re_viewer/badge.svg)](https://docs.rs/re_viewer?speculative-link) +[![Latest version](https://img.shields.io/crates/v/re_viewer.svg)](https://crates.io/crates/viewer/re_viewer) +[![Documentation](https://docs.rs/re_viewer/badge.svg)](https://docs.rs/re_viewer) ![MIT](https://img.shields.io/badge/license-MIT-blue.svg) ![Apache](https://img.shields.io/badge/license-Apache-blue.svg) diff --git a/crates/viewer/re_viewer_context/Cargo.toml b/crates/viewer/re_viewer_context/Cargo.toml index a0768622da06..e8cf0eef90d3 100644 --- a/crates/viewer/re_viewer_context/Cargo.toml +++ b/crates/viewer/re_viewer_context/Cargo.toml @@ -74,6 +74,7 @@ wgpu.workspace = true arboard = { workspace = true, default-features = false, features = [ "image-data", ] } +home.workspace = true # Web dependencies: [target.'cfg(target_arch = "wasm32")'.dependencies] diff --git a/crates/viewer/re_viewer_context/README.md b/crates/viewer/re_viewer_context/README.md index fa3ef603ddc5..7edbbaaf7fde 100644 --- a/crates/viewer/re_viewer_context/README.md +++ b/crates/viewer/re_viewer_context/README.md @@ -2,8 +2,8 @@ Part of the [`rerun`](https://github.com/rerun-io/rerun) family of crates. -[![Latest version](https://img.shields.io/crates/v/re_viewer_context.svg)](https://crates.io/crates/viewer/re_viewer_context?speculative-link) -[![Documentation](https://docs.rs/re_viewer_context/badge.svg)](https://docs.rs/re_viewer_context?speculative-link) +[![Latest version](https://img.shields.io/crates/v/re_viewer_context.svg)](https://crates.io/crates/viewer/re_viewer_context) +[![Documentation](https://docs.rs/re_viewer_context/badge.svg)](https://docs.rs/re_viewer_context) ![MIT](https://img.shields.io/badge/license-MIT-blue.svg) ![Apache](https://img.shields.io/badge/license-Apache-blue.svg) diff --git a/crates/viewer/re_viewport/README.md b/crates/viewer/re_viewport/README.md index b6bf90cd4967..8bd5548bbb5e 100644 --- a/crates/viewer/re_viewport/README.md +++ b/crates/viewer/re_viewport/README.md @@ -2,8 +2,8 @@ Part of the [`rerun`](https://github.com/rerun-io/rerun) family of crates. -[![Latest version](https://img.shields.io/crates/v/re_viewport.svg)](https://crates.io/crates/re_viewport?speculative-link) -[![Documentation](https://docs.rs/re_viewport/badge.svg)](https://docs.rs/re_viewport?speculative-link) +[![Latest version](https://img.shields.io/crates/v/re_viewport.svg)](https://crates.io/crates/re_viewport) +[![Documentation](https://docs.rs/re_viewport/badge.svg)](https://docs.rs/re_viewport) ![MIT](https://img.shields.io/badge/license-MIT-blue.svg) ![Apache](https://img.shields.io/badge/license-Apache-blue.svg) diff --git a/crates/viewer/re_viewport_blueprint/README.md b/crates/viewer/re_viewport_blueprint/README.md index ee8c229a13c8..8280a9e5d34b 100644 --- a/crates/viewer/re_viewport_blueprint/README.md +++ b/crates/viewer/re_viewport_blueprint/README.md @@ -2,8 +2,8 @@ Part of the [`rerun`](https://github.com/rerun-io/rerun) family of crates. -[![Latest version](https://img.shields.io/crates/v/re_viewport_blueprint.svg)](https://crates.io/crates/re_viewport_blueprint?speculative-link) -[![Documentation](https://docs.rs/re_viewport_blueprint/badge.svg)](https://docs.rs/re_viewport_blueprint?speculative-link) +[![Latest version](https://img.shields.io/crates/v/re_viewport_blueprint.svg)](https://crates.io/crates/re_viewport_blueprint) +[![Documentation](https://docs.rs/re_viewport_blueprint/badge.svg)](https://docs.rs/re_viewport_blueprint) ![MIT](https://img.shields.io/badge/license-MIT-blue.svg) ![Apache](https://img.shields.io/badge/license-Apache-blue.svg) diff --git a/docs/content/howto/logging/send-columns.md b/docs/content/howto/logging/send-columns.md index 07c6051e8c08..a1b28109f65f 100644 --- a/docs/content/howto/logging/send-columns.md +++ b/docs/content/howto/logging/send-columns.md @@ -33,7 +33,7 @@ snippet: archetypes/points3d_send_columns.py ### Using `send_columns` for logging custom components -An entire batch of a custom component can be logged at once using [`rr.AnyBatchValue`](https://ref.rerun.io/docs/python/0.20.0/common/custom_data/#rerun.AnyBatchValue?speculative-link) along with `send_column`: +An entire batch of a custom component can be logged at once using [`rr.AnyBatchValue`](https://ref.rerun.io/docs/python/0.20.0/common/custom_data/#rerun.AnyBatchValue) along with `send_column`: snippet: howto/any_batch_value_send_columns diff --git a/docs/content/reference/migration/migration-0-21.md b/docs/content/reference/migration/migration-0-21.md index 84a720a41338..481c17a509bb 100644 --- a/docs/content/reference/migration/migration-0-21.md +++ b/docs/content/reference/migration/migration-0-21.md @@ -29,14 +29,15 @@ rr.send_blueprint( ``` -### Types and fields got renamed from `.*space_view.*`/`.*SpaceView.*` to `.*view.*`/`.*View.*` +### Blueprint types and fields got renamed from `.*space_view.*`/`.*SpaceView.*` to `.*view.*`/`.*View.*` Various types and fields got changed to refer to "views" rather than "space views". -This exclusively affects the Python blueprint sdk: +This exclusively affects the Python blueprint sdk. -#### Field/argument changes: -* `ViewportBlueprint(...auto_views=...)` -> `ViewportBlueprint(...auto_views=...)` -* `Blueprint(...auto_views=...)` -> `Blueprint(...auto_views=...)` +#### Field/argument changes + +* `ViewportBlueprint(...auto_space_views=...)` -> `ViewportBlueprint(...auto_views=...)` +* `Blueprint(...auto_space_views=...)` -> `Blueprint(...auto_views=...)` #### Type changes diff --git a/docs/content/reference/types/archetypes/graph_edges.md b/docs/content/reference/types/archetypes/graph_edges.md index 47dc62ca7791..de405287b53b 100644 --- a/docs/content/reference/types/archetypes/graph_edges.md +++ b/docs/content/reference/types/archetypes/graph_edges.md @@ -3,9 +3,6 @@ title: "GraphEdges" --- - -⚠️ **This is an experimental API! It is not fully supported, and is likely to change significantly in future versions.** - A list of edges in a graph. By default, edges are undirected. @@ -21,9 +18,9 @@ By default, edges are undirected. * [DataframeView](../views/dataframe_view.md) ## API reference links - * 🌊 [C++ API docs for `GraphEdges`](https://ref.rerun.io/docs/cpp/stable/structrerun_1_1archetypes_1_1GraphEdges.html?speculative-link) - * 🐍 [Python API docs for `GraphEdges`](https://ref.rerun.io/docs/python/stable/common/archetypes?speculative-link#rerun.archetypes.GraphEdges) - * πŸ¦€ [Rust API docs for `GraphEdges`](https://docs.rs/rerun/latest/rerun/archetypes/struct.GraphEdges.html?speculative-link) + * 🌊 [C++ API docs for `GraphEdges`](https://ref.rerun.io/docs/cpp/stable/structrerun_1_1archetypes_1_1GraphEdges.html) + * 🐍 [Python API docs for `GraphEdges`](https://ref.rerun.io/docs/python/stable/common/archetypes#rerun.archetypes.GraphEdges) + * πŸ¦€ [Rust API docs for `GraphEdges`](https://docs.rs/rerun/latest/rerun/archetypes/struct.GraphEdges.html) ## Examples diff --git a/docs/content/reference/types/archetypes/graph_nodes.md b/docs/content/reference/types/archetypes/graph_nodes.md index c5b6d38ebab0..69fc86ddb4da 100644 --- a/docs/content/reference/types/archetypes/graph_nodes.md +++ b/docs/content/reference/types/archetypes/graph_nodes.md @@ -3,9 +3,6 @@ title: "GraphNodes" --- - -⚠️ **This is an experimental API! It is not fully supported, and is likely to change significantly in future versions.** - A list of nodes in a graph with optional labels, colors, etc. ## Components @@ -19,9 +16,9 @@ A list of nodes in a graph with optional labels, colors, etc. * [DataframeView](../views/dataframe_view.md) ## API reference links - * 🌊 [C++ API docs for `GraphNodes`](https://ref.rerun.io/docs/cpp/stable/structrerun_1_1archetypes_1_1GraphNodes.html?speculative-link) - * 🐍 [Python API docs for `GraphNodes`](https://ref.rerun.io/docs/python/stable/common/archetypes?speculative-link#rerun.archetypes.GraphNodes) - * πŸ¦€ [Rust API docs for `GraphNodes`](https://docs.rs/rerun/latest/rerun/archetypes/struct.GraphNodes.html?speculative-link) + * 🌊 [C++ API docs for `GraphNodes`](https://ref.rerun.io/docs/cpp/stable/structrerun_1_1archetypes_1_1GraphNodes.html) + * 🐍 [Python API docs for `GraphNodes`](https://ref.rerun.io/docs/python/stable/common/archetypes#rerun.archetypes.GraphNodes) + * πŸ¦€ [Rust API docs for `GraphNodes`](https://docs.rs/rerun/latest/rerun/archetypes/struct.GraphNodes.html) ## Examples diff --git a/docs/content/reference/types/components/color.md b/docs/content/reference/types/components/color.md index 7e28f1ebae84..835488c2c0cf 100644 --- a/docs/content/reference/types/components/color.md +++ b/docs/content/reference/types/components/color.md @@ -34,7 +34,7 @@ uint32 * [`Ellipsoids3D`](../archetypes/ellipsoids3d.md) * [`GeoLineStrings`](../archetypes/geo_line_strings.md) * [`GeoPoints`](../archetypes/geo_points.md) -* [`GraphNodes`](../archetypes/graph_nodes.md?speculative-link) +* [`GraphNodes`](../archetypes/graph_nodes.md) * [`LineStrips2D`](../archetypes/line_strips2d.md) * [`LineStrips3D`](../archetypes/line_strips3d.md) * [`Mesh3D`](../archetypes/mesh3d.md) diff --git a/docs/content/reference/types/components/graph_edge.md b/docs/content/reference/types/components/graph_edge.md index 7e3d6a7a8300..002d4ef6010f 100644 --- a/docs/content/reference/types/components/graph_edge.md +++ b/docs/content/reference/types/components/graph_edge.md @@ -18,11 +18,11 @@ Struct { ``` ## API reference links - * 🌊 [C++ API docs for `GraphEdge`](https://ref.rerun.io/docs/cpp/stable/structrerun_1_1components_1_1GraphEdge.html?speculative-link) - * 🐍 [Python API docs for `GraphEdge`](https://ref.rerun.io/docs/python/stable/common/components?speculative-link#rerun.components.GraphEdge) - * πŸ¦€ [Rust API docs for `GraphEdge`](https://docs.rs/rerun/latest/rerun/components/struct.GraphEdge.html?speculative-link) + * 🌊 [C++ API docs for `GraphEdge`](https://ref.rerun.io/docs/cpp/stable/structrerun_1_1components_1_1GraphEdge.html) + * 🐍 [Python API docs for `GraphEdge`](https://ref.rerun.io/docs/python/stable/common/components#rerun.components.GraphEdge) + * πŸ¦€ [Rust API docs for `GraphEdge`](https://docs.rs/rerun/latest/rerun/components/struct.GraphEdge.html) ## Used by -* [`GraphEdges`](../archetypes/graph_edges.md?speculative-link) +* [`GraphEdges`](../archetypes/graph_edges.md) diff --git a/docs/content/reference/types/components/graph_node.md b/docs/content/reference/types/components/graph_node.md index 23e0732351b0..638c20cf3217 100644 --- a/docs/content/reference/types/components/graph_node.md +++ b/docs/content/reference/types/components/graph_node.md @@ -15,11 +15,11 @@ utf8 ``` ## API reference links - * 🌊 [C++ API docs for `GraphNode`](https://ref.rerun.io/docs/cpp/stable/structrerun_1_1components_1_1GraphNode.html?speculative-link) - * 🐍 [Python API docs for `GraphNode`](https://ref.rerun.io/docs/python/stable/common/components?speculative-link#rerun.components.GraphNode) - * πŸ¦€ [Rust API docs for `GraphNode`](https://docs.rs/rerun/latest/rerun/components/struct.GraphNode.html?speculative-link) + * 🌊 [C++ API docs for `GraphNode`](https://ref.rerun.io/docs/cpp/stable/structrerun_1_1components_1_1GraphNode.html) + * 🐍 [Python API docs for `GraphNode`](https://ref.rerun.io/docs/python/stable/common/components#rerun.components.GraphNode) + * πŸ¦€ [Rust API docs for `GraphNode`](https://docs.rs/rerun/latest/rerun/components/struct.GraphNode.html) ## Used by -* [`GraphNodes`](../archetypes/graph_nodes.md?speculative-link) +* [`GraphNodes`](../archetypes/graph_nodes.md) diff --git a/docs/content/reference/types/components/graph_type.md b/docs/content/reference/types/components/graph_type.md index 5bb3a94c79ec..24aa3323c707 100644 --- a/docs/content/reference/types/components/graph_type.md +++ b/docs/content/reference/types/components/graph_type.md @@ -19,11 +19,11 @@ uint8 ``` ## API reference links - * 🌊 [C++ API docs for `GraphType`](https://ref.rerun.io/docs/cpp/stable/namespacererun_1_1components.html?speculative-link) - * 🐍 [Python API docs for `GraphType`](https://ref.rerun.io/docs/python/stable/common/components?speculative-link#rerun.components.GraphType) - * πŸ¦€ [Rust API docs for `GraphType`](https://docs.rs/rerun/latest/rerun/components/enum.GraphType.html?speculative-link) + * 🌊 [C++ API docs for `GraphType`](https://ref.rerun.io/docs/cpp/stable/namespacererun_1_1components.html) + * 🐍 [Python API docs for `GraphType`](https://ref.rerun.io/docs/python/stable/common/components#rerun.components.GraphType) + * πŸ¦€ [Rust API docs for `GraphType`](https://docs.rs/rerun/latest/rerun/components/enum.GraphType.html) ## Used by -* [`GraphEdges`](../archetypes/graph_edges.md?speculative-link) +* [`GraphEdges`](../archetypes/graph_edges.md) diff --git a/docs/content/reference/types/components/plane3d.md b/docs/content/reference/types/components/plane3d.md index 58d7e4e31c40..4dc7f25f7c0c 100644 --- a/docs/content/reference/types/components/plane3d.md +++ b/docs/content/reference/types/components/plane3d.md @@ -23,8 +23,8 @@ FixedSizeList<4, float32> ``` ## API reference links - * 🌊 [C++ API docs for `Plane3D`](https://ref.rerun.io/docs/cpp/stable/structrerun_1_1components_1_1Plane3D.html?speculative-link) - * 🐍 [Python API docs for `Plane3D`](https://ref.rerun.io/docs/python/stable/common/components?speculative-link#rerun.components.Plane3D) - * πŸ¦€ [Rust API docs for `Plane3D`](https://docs.rs/rerun/latest/rerun/components/struct.Plane3D.html?speculative-link) + * 🌊 [C++ API docs for `Plane3D`](https://ref.rerun.io/docs/cpp/stable/structrerun_1_1components_1_1Plane3D.html) + * 🐍 [Python API docs for `Plane3D`](https://ref.rerun.io/docs/python/stable/common/components#rerun.components.Plane3D) + * πŸ¦€ [Rust API docs for `Plane3D`](https://docs.rs/rerun/latest/rerun/components/struct.Plane3D.html) diff --git a/docs/content/reference/types/components/position2d.md b/docs/content/reference/types/components/position2d.md index faa24a3318ab..78f839ff55db 100644 --- a/docs/content/reference/types/components/position2d.md +++ b/docs/content/reference/types/components/position2d.md @@ -24,5 +24,5 @@ FixedSizeList<2, float32> * [`Arrows2D`](../archetypes/arrows2d.md) * [`Boxes2D`](../archetypes/boxes2d.md) -* [`GraphNodes`](../archetypes/graph_nodes.md?speculative-link) +* [`GraphNodes`](../archetypes/graph_nodes.md) * [`Points2D`](../archetypes/points2d.md) diff --git a/docs/content/reference/types/components/radius.md b/docs/content/reference/types/components/radius.md index 3d976dd859d9..e0ded53ec2f4 100644 --- a/docs/content/reference/types/components/radius.md +++ b/docs/content/reference/types/components/radius.md @@ -37,7 +37,7 @@ float32 * [`Ellipsoids3D`](../archetypes/ellipsoids3d.md) * [`GeoLineStrings`](../archetypes/geo_line_strings.md) * [`GeoPoints`](../archetypes/geo_points.md) -* [`GraphNodes`](../archetypes/graph_nodes.md?speculative-link) +* [`GraphNodes`](../archetypes/graph_nodes.md) * [`LineStrips2D`](../archetypes/line_strips2d.md) * [`LineStrips3D`](../archetypes/line_strips3d.md) * [`Points2D`](../archetypes/points2d.md) diff --git a/docs/content/reference/types/components/recording_uri.md b/docs/content/reference/types/components/recording_uri.md index 99133fc12b35..0e002267a23d 100644 --- a/docs/content/reference/types/components/recording_uri.md +++ b/docs/content/reference/types/components/recording_uri.md @@ -15,8 +15,8 @@ utf8 ``` ## API reference links - * 🌊 [C++ API docs for `RecordingUri`](https://ref.rerun.io/docs/cpp/stable/structrerun_1_1components_1_1RecordingUri.html?speculative-link) - * 🐍 [Python API docs for `RecordingUri`](https://ref.rerun.io/docs/python/stable/common/components?speculative-link#rerun.components.RecordingUri) - * πŸ¦€ [Rust API docs for `RecordingUri`](https://docs.rs/rerun/latest/rerun/components/struct.RecordingUri.html?speculative-link) + * 🌊 [C++ API docs for `RecordingUri`](https://ref.rerun.io/docs/cpp/stable/structrerun_1_1components_1_1RecordingUri.html) + * 🐍 [Python API docs for `RecordingUri`](https://ref.rerun.io/docs/python/stable/common/components#rerun.components.RecordingUri) + * πŸ¦€ [Rust API docs for `RecordingUri`](https://docs.rs/rerun/latest/rerun/components/struct.RecordingUri.html) diff --git a/docs/content/reference/types/components/show_labels.md b/docs/content/reference/types/components/show_labels.md index 1f81d6c88e8f..81c2df55751c 100644 --- a/docs/content/reference/types/components/show_labels.md +++ b/docs/content/reference/types/components/show_labels.md @@ -32,7 +32,7 @@ boolean * [`Boxes3D`](../archetypes/boxes3d.md) * [`Capsules3D`](../archetypes/capsules3d.md) * [`Ellipsoids3D`](../archetypes/ellipsoids3d.md) -* [`GraphNodes`](../archetypes/graph_nodes.md?speculative-link) +* [`GraphNodes`](../archetypes/graph_nodes.md) * [`LineStrips2D`](../archetypes/line_strips2d.md) * [`LineStrips3D`](../archetypes/line_strips3d.md) * [`Points2D`](../archetypes/points2d.md) diff --git a/docs/content/reference/types/components/text.md b/docs/content/reference/types/components/text.md index 456c2fc088df..c4dfafa3c62d 100644 --- a/docs/content/reference/types/components/text.md +++ b/docs/content/reference/types/components/text.md @@ -28,7 +28,7 @@ utf8 * [`Boxes3D`](../archetypes/boxes3d.md) * [`Capsules3D`](../archetypes/capsules3d.md) * [`Ellipsoids3D`](../archetypes/ellipsoids3d.md) -* [`GraphNodes`](../archetypes/graph_nodes.md?speculative-link) +* [`GraphNodes`](../archetypes/graph_nodes.md) * [`LineStrips2D`](../archetypes/line_strips2d.md) * [`LineStrips3D`](../archetypes/line_strips3d.md) * [`Points2D`](../archetypes/points2d.md) diff --git a/docs/content/reference/types/datatypes/plane3d.md b/docs/content/reference/types/datatypes/plane3d.md index 3f0973d64b6d..94cb6e572b38 100644 --- a/docs/content/reference/types/datatypes/plane3d.md +++ b/docs/content/reference/types/datatypes/plane3d.md @@ -20,11 +20,11 @@ FixedSizeList<4, float32> ``` ## API reference links - * 🌊 [C++ API docs for `Plane3D`](https://ref.rerun.io/docs/cpp/stable/structrerun_1_1datatypes_1_1Plane3D.html?speculative-link) - * 🐍 [Python API docs for `Plane3D`](https://ref.rerun.io/docs/python/stable/common/datatypes?speculative-link#rerun.datatypes.Plane3D) - * πŸ¦€ [Rust API docs for `Plane3D`](https://docs.rs/rerun/latest/rerun/datatypes/struct.Plane3D.html?speculative-link) + * 🌊 [C++ API docs for `Plane3D`](https://ref.rerun.io/docs/cpp/stable/structrerun_1_1datatypes_1_1Plane3D.html) + * 🐍 [Python API docs for `Plane3D`](https://ref.rerun.io/docs/python/stable/common/datatypes#rerun.datatypes.Plane3D) + * πŸ¦€ [Rust API docs for `Plane3D`](https://docs.rs/rerun/latest/rerun/datatypes/struct.Plane3D.html) ## Used by -* [`Plane3D`](../components/plane3d.md?speculative-link) +* [`Plane3D`](../components/plane3d.md) diff --git a/docs/content/reference/types/datatypes/utf8.md b/docs/content/reference/types/datatypes/utf8.md index b4180a94ad44..092555b91625 100644 --- a/docs/content/reference/types/datatypes/utf8.md +++ b/docs/content/reference/types/datatypes/utf8.md @@ -20,11 +20,11 @@ utf8 ## Used by * [`AnnotationInfo`](../datatypes/annotation_info.md) -* [`GraphNode`](../components/graph_node.md?speculative-link) +* [`GraphNode`](../components/graph_node.md) * [`MediaType`](../components/media_type.md) * [`Name`](../components/name.md) -* [`RecordingUri`](../components/recording_uri.md?speculative-link) +* [`RecordingUri`](../components/recording_uri.md) * [`TextLogLevel`](../components/text_log_level.md) * [`Text`](../components/text.md) -* [`Utf8Pair`](../datatypes/utf8pair.md?speculative-link) +* [`Utf8Pair`](../datatypes/utf8pair.md) * [`VisibleTimeRange`](../datatypes/visible_time_range.md) diff --git a/docs/content/reference/types/datatypes/utf8pair.md b/docs/content/reference/types/datatypes/utf8pair.md index 1815cd16438e..15cb7fb87d49 100644 --- a/docs/content/reference/types/datatypes/utf8pair.md +++ b/docs/content/reference/types/datatypes/utf8pair.md @@ -26,11 +26,11 @@ Struct { ``` ## API reference links - * 🌊 [C++ API docs for `Utf8Pair`](https://ref.rerun.io/docs/cpp/stable/structrerun_1_1datatypes_1_1Utf8Pair.html?speculative-link) - * 🐍 [Python API docs for `Utf8Pair`](https://ref.rerun.io/docs/python/stable/common/datatypes?speculative-link#rerun.datatypes.Utf8Pair) - * πŸ¦€ [Rust API docs for `Utf8Pair`](https://docs.rs/rerun/latest/rerun/datatypes/struct.Utf8Pair.html?speculative-link) + * 🌊 [C++ API docs for `Utf8Pair`](https://ref.rerun.io/docs/cpp/stable/structrerun_1_1datatypes_1_1Utf8Pair.html) + * 🐍 [Python API docs for `Utf8Pair`](https://ref.rerun.io/docs/python/stable/common/datatypes#rerun.datatypes.Utf8Pair) + * πŸ¦€ [Rust API docs for `Utf8Pair`](https://docs.rs/rerun/latest/rerun/datatypes/struct.Utf8Pair.html) ## Used by -* [`GraphEdge`](../components/graph_edge.md?speculative-link) +* [`GraphEdge`](../components/graph_edge.md) diff --git a/docs/content/reference/types/views/graph_view.md b/docs/content/reference/types/views/graph_view.md index e222d74616b7..e76a96c14613 100644 --- a/docs/content/reference/types/views/graph_view.md +++ b/docs/content/reference/types/views/graph_view.md @@ -41,7 +41,7 @@ Tries to move the center of mass of the graph to the origin. * `strength`: The strength of the force. ## API reference links - * 🐍 [Python API docs for `GraphView`](https://ref.rerun.io/docs/python/stable/common/blueprint_views?speculative-link#rerun.blueprint.views.GraphView) + * 🐍 [Python API docs for `GraphView`](https://ref.rerun.io/docs/python/stable/common/blueprint_views#rerun.blueprint.views.GraphView) ## Example diff --git a/docs/snippets/INDEX.md b/docs/snippets/INDEX.md index d64fed561048..16ee05d96c03 100644 --- a/docs/snippets/INDEX.md +++ b/docs/snippets/INDEX.md @@ -25,7 +25,7 @@ Use it to quickly find copy-pastable snippets of code for any Rerun feature you' | **Dataframes** | `dataframe_query` | Query and display the first 10 rows of a recording | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/reference/dataframe_query.py) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/reference/dataframe_query.rs) | | | **Dataframes** | `dataframe_view_query` | Query and display the first 10 rows of a recording in a dataframe view | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/reference/dataframe_view_query.py) | | | | **`AnyValue`** | `any_values` | Log arbitrary data | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/tutorials/any_values.py) | | | -| **`AnyValue`** | `any_values_send_columns` | Use `AnyValues` and `send_column` to send entire columns of custom data to Rerun | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/howto/any_values_send_columns.py?speculative-link) | | | +| **`AnyValue`** | `any_values_send_columns` | Use `AnyValues` and `send_column` to send entire columns of custom data to Rerun | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/howto/any_values_send_columns.py) | | | | **`AnyValue`** | `extra_values` | Log extra values with a Points2D | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/tutorials/extra_values.py) | | | @@ -82,11 +82,11 @@ _All snippets, organized by the [`Archetype`](https://rerun.io/docs/reference/ty | **[`GeoLineStrings`](https://rerun.io/docs/reference/types/archetypes/geo_line_strings)** | `archetypes/geo_line_strings_simple` | Log a simple geospatial line string | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/geo_line_strings_simple.py) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/geo_line_strings_simple.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/geo_line_strings_simple.cpp) | | **[`GeoPoints`](https://rerun.io/docs/reference/types/archetypes/geo_points)** | `archetypes/geo_points_simple` | Log some very simple geospatial point | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/geo_points_simple.py) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/geo_points_simple.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/geo_points_simple.cpp) | | **[`GeoPoints`](https://rerun.io/docs/reference/types/archetypes/geo_points)** | `views/map` | Use a blueprint to customize a map view | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/views/map.py) | | | -| **[`GraphEdges`](https://rerun.io/docs/reference/types/archetypes/graph_edges?speculative-link)** | `archetypes/graph_directed` | Log a simple directed graph | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_directed.py?speculative-link) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_directed.rs?speculative-link) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_directed.cpp?speculative-link) | -| **[`GraphEdges`](https://rerun.io/docs/reference/types/archetypes/graph_edges?speculative-link)** | `archetypes/graph_undirected` | Log a simple undirected graph | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_undirected.py?speculative-link) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_undirected.rs?speculative-link) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_undirected.cpp?speculative-link) | -| **[`GraphNodes`](https://rerun.io/docs/reference/types/archetypes/graph_nodes?speculative-link)** | `archetypes/graph_directed` | Log a simple directed graph | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_directed.py?speculative-link) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_directed.rs?speculative-link) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_directed.cpp?speculative-link) | -| **[`GraphNodes`](https://rerun.io/docs/reference/types/archetypes/graph_nodes?speculative-link)** | `archetypes/graph_undirected` | Log a simple undirected graph | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_undirected.py?speculative-link) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_undirected.rs?speculative-link) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_undirected.cpp?speculative-link) | -| **[`GraphNodes`](https://rerun.io/docs/reference/types/archetypes/graph_nodes?speculative-link)** | `views/graph` | Use a blueprint to customize a graph view | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/views/graph.py?speculative-link?speculative-link) | | | +| **[`GraphEdges`](https://rerun.io/docs/reference/types/archetypes/graph_edges)** | `archetypes/graph_directed` | Log a simple directed graph | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_directed.py) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_directed.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_directed.cpp) | +| **[`GraphEdges`](https://rerun.io/docs/reference/types/archetypes/graph_edges)** | `archetypes/graph_undirected` | Log a simple undirected graph | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_undirected.py) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_undirected.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_undirected.cpp) | +| **[`GraphNodes`](https://rerun.io/docs/reference/types/archetypes/graph_nodes)** | `archetypes/graph_directed` | Log a simple directed graph | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_directed.py) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_directed.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_directed.cpp) | +| **[`GraphNodes`](https://rerun.io/docs/reference/types/archetypes/graph_nodes)** | `archetypes/graph_undirected` | Log a simple undirected graph | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_undirected.py) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_undirected.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_undirected.cpp) | +| **[`GraphNodes`](https://rerun.io/docs/reference/types/archetypes/graph_nodes)** | `views/graph` | Use a blueprint to customize a graph view | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/views/graph.py) | | | | **[`Image`](https://rerun.io/docs/reference/types/archetypes/image)** | `archetypes/segmentation_image_simple` | Create and log a segmentation image | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/segmentation_image_simple.py) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/segmentation_image_simple.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/segmentation_image_simple.cpp) | | **[`Image`](https://rerun.io/docs/reference/types/archetypes/image)** | `archetypes/image_simple` | Create and log an image | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/image_simple.py) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/image_simple.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/image_simple.cpp) | | **[`Image`](https://rerun.io/docs/reference/types/archetypes/image)** | `archetypes/image_send_columns` | Send multiple images at once using `send_columns` | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/image_send_columns.py) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/image_send_columns.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/image_send_columns.cpp) | @@ -135,9 +135,9 @@ _All snippets, organized by the [`Archetype`](https://rerun.io/docs/reference/ty | **[`Points3D`](https://rerun.io/docs/reference/types/archetypes/points3d)** | `archetypes/instance_poses3d_combined` | Log a simple 3D box with a regular & instance pose transform | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/instance_poses3d_combined.py) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/instance_poses3d_combined.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/instance_poses3d_combined.cpp) | | **[`Points3D`](https://rerun.io/docs/reference/types/archetypes/points3d)** | `archetypes/pinhole_perspective` | Logs a point cloud and a perspective camera looking at it | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/pinhole_perspective.py) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/pinhole_perspective.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/pinhole_perspective.cpp) | | **[`Points3D`](https://rerun.io/docs/reference/types/archetypes/points3d)** | `archetypes/transform3d_hierarchy` | Logs a transforms transform hierarchy | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/transform3d_hierarchy.py) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/transform3d_hierarchy.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/transform3d_hierarchy.cpp) | -| **[`Points3D`](https://rerun.io/docs/reference/types/archetypes/points3d)** | `concepts/explicit_recording` | Just makes sure that explicit recordings actually work | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/explicit_recording.py?speculative-link) | | | -| **[`Points3D`](https://rerun.io/docs/reference/types/archetypes/points3d)** | `descriptors/descr_builtin_archetype` | | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/descriptors/descr_builtin_archetype.py?speculative-link) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/descriptors/descr_builtin_archetype.rs?speculative-link) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/descriptors/descr_builtin_archetype.cpp?speculative-link) | -| **[`Points3D`](https://rerun.io/docs/reference/types/archetypes/points3d)** | `descriptors/descr_custom_archetype` | | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/descriptors/descr_custom_archetype.py?speculative-link) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/descriptors/descr_custom_archetype.rs?speculative-link) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/descriptors/descr_custom_archetype.cpp?speculative-link) | +| **[`Points3D`](https://rerun.io/docs/reference/types/archetypes/points3d)** | `concepts/explicit_recording` | Just makes sure that explicit recordings actually work | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/explicit_recording.py) | | | +| **[`Points3D`](https://rerun.io/docs/reference/types/archetypes/points3d)** | `descriptors/descr_builtin_archetype` | | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/descriptors/descr_builtin_archetype.py) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/descriptors/descr_builtin_archetype.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/descriptors/descr_builtin_archetype.cpp) | +| **[`Points3D`](https://rerun.io/docs/reference/types/archetypes/points3d)** | `descriptors/descr_custom_archetype` | | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/descriptors/descr_custom_archetype.py) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/descriptors/descr_custom_archetype.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/descriptors/descr_custom_archetype.cpp) | | **[`Points3D`](https://rerun.io/docs/reference/types/archetypes/points3d)** | `migration/log_line` | | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/migration/log_line.py) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/migration/log_line.rs) | | | **[`Points3D`](https://rerun.io/docs/reference/types/archetypes/points3d)** | `quick_start/quick_start_connect` | Connect to the viewer and log some data | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/quick_start/quick_start_connect.py) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/quick_start/quick_start_connect.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/quick_start/quick_start_connect.cpp) | | **[`Points3D`](https://rerun.io/docs/reference/types/archetypes/points3d)** | `quick_start/quick_start_spawn` | Spawn a viewer and log some data | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/quick_start/quick_start_spawn.py) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/quick_start/quick_start_spawn.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/quick_start/quick_start_spawn.cpp) | @@ -204,25 +204,25 @@ _All snippets, organized by the [`Component`](https://rerun.io/docs/reference/ty | **[`Color`](https://rerun.io/docs/reference/types/components/color)** | `concepts/viscomp-component-override` | Override a component | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/viscomp-component-override.py) | | | | **[`Color`](https://rerun.io/docs/reference/types/components/color)** | `concepts/viscomp-visualizer-override` | Override a visualizer | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/viscomp-visualizer-override.py) | | | | **[`Color`](https://rerun.io/docs/reference/types/components/color)** | `concepts/viscomp-visualizer-override-multiple` | Override a visualizer | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/viscomp-visualizer-override-multiple.py) | | | -| **[`Color`](https://rerun.io/docs/reference/types/components/color)** | `descriptors/descr_custom_archetype` | | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/descriptors/descr_custom_archetype.py?speculative-link) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/descriptors/descr_custom_archetype.rs?speculative-link) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/descriptors/descr_custom_archetype.cpp?speculative-link) | +| **[`Color`](https://rerun.io/docs/reference/types/components/color)** | `descriptors/descr_custom_archetype` | | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/descriptors/descr_custom_archetype.py) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/descriptors/descr_custom_archetype.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/descriptors/descr_custom_archetype.cpp) | | **[`Color`](https://rerun.io/docs/reference/types/components/color)** | `views/spatial3d` | Use a blueprint to customize a Spatial3DView | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/views/spatial3d.py) | | | | **[`DisconnectedSpace`](https://rerun.io/docs/reference/types/components/disconnected_space)** | `archetypes/disconnected_space` | Disconnect two spaces | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/disconnected_space.py) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/disconnected_space.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/disconnected_space.cpp) | | **[`GeoLineString`](https://rerun.io/docs/reference/types/components/geo_line_string)** | `archetypes/geo_line_strings_simple` | Log a simple geospatial line string | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/geo_line_strings_simple.py) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/geo_line_strings_simple.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/geo_line_strings_simple.cpp) | -| **[`GraphEdge`](https://rerun.io/docs/reference/types/components/graph_edge?speculative-link)** | `archetypes/graph_directed` | Log a simple directed graph | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_directed.py?speculative-link) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_directed.rs?speculative-link) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_directed.cpp?speculative-link) | -| **[`GraphEdge`](https://rerun.io/docs/reference/types/components/graph_edge?speculative-link)** | `archetypes/graph_undirected` | Log a simple undirected graph | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_undirected.py?speculative-link) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_undirected.rs?speculative-link) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_undirected.cpp?speculative-link) | -| **[`GraphNode`](https://rerun.io/docs/reference/types/components/graph_node?speculative-link)** | `archetypes/graph_directed` | Log a simple directed graph | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_directed.py?speculative-link) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_directed.rs?speculative-link) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_directed.cpp?speculative-link) | -| **[`GraphNode`](https://rerun.io/docs/reference/types/components/graph_node?speculative-link)** | `archetypes/graph_undirected` | Log a simple undirected graph | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_undirected.py?speculative-link) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_undirected.rs?speculative-link) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_undirected.cpp?speculative-link) | -| **[`GraphNode`](https://rerun.io/docs/reference/types/components/graph_node?speculative-link)** | `views/graph` | Use a blueprint to customize a graph view | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/views/graph.py?speculative-link?speculative-link) | | | +| **[`GraphEdge`](https://rerun.io/docs/reference/types/components/graph_edge)** | `archetypes/graph_directed` | Log a simple directed graph | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_directed.py) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_directed.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_directed.cpp) | +| **[`GraphEdge`](https://rerun.io/docs/reference/types/components/graph_edge)** | `archetypes/graph_undirected` | Log a simple undirected graph | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_undirected.py) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_undirected.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_undirected.cpp) | +| **[`GraphNode`](https://rerun.io/docs/reference/types/components/graph_node)** | `archetypes/graph_directed` | Log a simple directed graph | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_directed.py) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_directed.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_directed.cpp) | +| **[`GraphNode`](https://rerun.io/docs/reference/types/components/graph_node)** | `archetypes/graph_undirected` | Log a simple undirected graph | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_undirected.py) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_undirected.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_undirected.cpp) | +| **[`GraphNode`](https://rerun.io/docs/reference/types/components/graph_node)** | `views/graph` | Use a blueprint to customize a graph view | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/views/graph.py) | | | | **[`ImageBuffer`](https://rerun.io/docs/reference/types/components/image_buffer)** | `archetypes/image_send_columns` | Send multiple images at once using `send_columns` | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/image_send_columns.py) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/image_send_columns.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/image_send_columns.cpp) | | **[`ImageFormat`](https://rerun.io/docs/reference/types/components/image_format)** | `archetypes/image_send_columns` | Send multiple images at once using `send_columns` | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/image_send_columns.py) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/image_send_columns.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/image_send_columns.cpp) | | **[`MediaType`](https://rerun.io/docs/reference/types/components/media_type)** | `archetypes/text_document` | Log a `TextDocument` | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/text_document.py) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/text_document.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/text_document.cpp) | | **[`MediaType`](https://rerun.io/docs/reference/types/components/media_type)** | `views/text_document` | Use a blueprint to show a text document | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/views/text_document.py) | | | -| **[`Plane3D`](https://rerun.io/docs/reference/types/components/plane3d?speculative-link)** | `views/spatial3d` | Use a blueprint to customize a Spatial3DView | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/views/spatial3d.py?speculative-link) | | | +| **[`Plane3D`](https://rerun.io/docs/reference/types/components/plane3d)** | `views/spatial3d` | Use a blueprint to customize a Spatial3DView | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/views/spatial3d.py) | | | | **[`Position3D`](https://rerun.io/docs/reference/types/components/position3d)** | `archetypes/mesh3d_partial_updates` | Log a simple colored triangle, then update its vertices' positions each frame | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/mesh3d_partial_updates.py) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/mesh3d_partial_updates.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/mesh3d_partial_updates.cpp) | | **[`Position3D`](https://rerun.io/docs/reference/types/components/position3d)** | `archetypes/points3d_send_columns` | Use the `send_columns` API to send several point clouds over time in a single call | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_send_columns.py) | | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_send_columns.cpp) | -| **[`Position3D`](https://rerun.io/docs/reference/types/components/position3d)** | `descriptors/descr_builtin_component` | | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/descriptors/descr_builtin_component.py?speculative-link) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/descriptors/descr_builtin_component.rs?speculative-link) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/descriptors/descr_builtin_component.cpp?speculative-link) | -| **[`Position3D`](https://rerun.io/docs/reference/types/components/position3d)** | `descriptors/descr_custom_archetype` | | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/descriptors/descr_custom_archetype.py?speculative-link) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/descriptors/descr_custom_archetype.rs?speculative-link) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/descriptors/descr_custom_archetype.cpp?speculative-link) | -| **[`Position3D`](https://rerun.io/docs/reference/types/components/position3d)** | `descriptors/descr_custom_component` | | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/descriptors/descr_custom_component.py?speculative-link) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/descriptors/descr_custom_component.rs?speculative-link) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/descriptors/descr_custom_component.cpp?speculative-link) | +| **[`Position3D`](https://rerun.io/docs/reference/types/components/position3d)** | `descriptors/descr_builtin_component` | | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/descriptors/descr_builtin_component.py) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/descriptors/descr_builtin_component.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/descriptors/descr_builtin_component.cpp) | +| **[`Position3D`](https://rerun.io/docs/reference/types/components/position3d)** | `descriptors/descr_custom_archetype` | | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/descriptors/descr_custom_archetype.py) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/descriptors/descr_custom_archetype.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/descriptors/descr_custom_archetype.cpp) | +| **[`Position3D`](https://rerun.io/docs/reference/types/components/position3d)** | `descriptors/descr_custom_component` | | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/descriptors/descr_custom_component.py) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/descriptors/descr_custom_component.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/descriptors/descr_custom_component.cpp) | | **[`Radius`](https://rerun.io/docs/reference/types/components/radius)** | `archetypes/points3d_ui_radius` | Log some points with ui points & scene unit radii | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_ui_radius.py) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_ui_radius.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_ui_radius.cpp) | | **[`Radius`](https://rerun.io/docs/reference/types/components/radius)** | `archetypes/points2d_ui_radius` | Log some points with ui points & scene unit radii | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points2d_ui_radius.py) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points2d_ui_radius.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points2d_ui_radius.cpp) | | **[`Radius`](https://rerun.io/docs/reference/types/components/radius)** | `archetypes/line_strips3d_ui_radius` | Log lines with ui points & scene unit radii | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/line_strips3d_ui_radius.py) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/line_strips3d_ui_radius.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/line_strips3d_ui_radius.cpp) | @@ -280,7 +280,7 @@ _All snippets, organized by the [`View`](https://rerun.io/docs/reference/types/v | **[`DataframeView`](https://rerun.io/docs/reference/types/views/dataframe_view)** | `reference/dataframe_view_query` | Query and display the first 10 rows of a recording in a dataframe view | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/reference/dataframe_view_query.py) | | | | **[`DataframeView`](https://rerun.io/docs/reference/types/views/dataframe_view)** | `reference/dataframe_save_blueprint` | Craft a blueprint with the python API and save it to a file for future use | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/reference/dataframe_save_blueprint.py) | | | | **[`DataframeView`](https://rerun.io/docs/reference/types/views/dataframe_view)** | `views/dataframe` | Use a blueprint to customize a DataframeView | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/views/dataframe.py) | | | -| **[`GraphView`](https://rerun.io/docs/reference/types/views/graph_view?speculative-link)** | `views/graph` | Use a blueprint to customize a graph view | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/views/graph.py?speculative-link?speculative-link) | | | +| **[`GraphView`](https://rerun.io/docs/reference/types/views/graph_view)** | `views/graph` | Use a blueprint to customize a graph view | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/views/graph.py) | | | | **[`MapView`](https://rerun.io/docs/reference/types/views/map_view)** | `views/map` | Use a blueprint to customize a map view | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/views/map.py) | | | | **[`Spatial2DView`](https://rerun.io/docs/reference/types/views/spatial2d_view)** | `archetypes/line_strips2d_batch` | Log a batch of 2D line strips | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/line_strips2d_batch.py) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/line_strips2d_batch.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/line_strips2d_batch.cpp) | | **[`Spatial2DView`](https://rerun.io/docs/reference/types/views/spatial2d_view)** | `archetypes/line_strips2d_segments_simple` | Log a couple 2D line segments using 2D line strips | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/line_strips2d_segments_simple.py) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/line_strips2d_segments_simple.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/line_strips2d_segments_simple.cpp) | @@ -333,7 +333,7 @@ _All snippets, organized by the blueprint-related [`Archetype`](https://rerun.io | **`VisualBounds2D`** | `archetypes/points2d_ui_radius` | Log some points with ui points & scene unit radii | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points2d_ui_radius.py) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points2d_ui_radius.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points2d_ui_radius.cpp) | | **`VisualBounds2D`** | `concepts/different_data_per_timeline` | Log different data on different timelines | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/different_data_per_timeline.py) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/different_data_per_timeline.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/different_data_per_timeline.cpp) | | **`VisualBounds2D`** | `tutorials/extra_values` | Log extra values with a Points2D | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/tutorials/extra_values.py) | | | -| **`VisualBounds2D`** | `views/graph` | Use a blueprint to customize a graph view | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/views/graph.py?speculative-link) | | | +| **`VisualBounds2D`** | `views/graph` | Use a blueprint to customize a graph view | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/views/graph.py) | | | | **`VisualBounds2D`** | `views/spatial2d` | Use a blueprint to customize a Spatial2DView | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/views/spatial2d.py) | | | @@ -357,7 +357,7 @@ _All snippets, organized by the blueprint-related [`Component`](https://rerun.io | **`VisualBounds2D`** | `archetypes/points2d_ui_radius` | Log some points with ui points & scene unit radii | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points2d_ui_radius.py) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points2d_ui_radius.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points2d_ui_radius.cpp) | | **`VisualBounds2D`** | `concepts/different_data_per_timeline` | Log different data on different timelines | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/different_data_per_timeline.py) | [πŸ¦€](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/different_data_per_timeline.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/different_data_per_timeline.cpp) | | **`VisualBounds2D`** | `tutorials/extra_values` | Log extra values with a Points2D | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/tutorials/extra_values.py) | | | -| **`VisualBounds2D`** | `views/graph` | Use a blueprint to customize a graph view | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/views/graph.py?speculative-link) | | | +| **`VisualBounds2D`** | `views/graph` | Use a blueprint to customize a graph view | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/views/graph.py) | | | | **`VisualBounds2D`** | `views/spatial2d` | Use a blueprint to customize a Spatial2DView | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/views/spatial2d.py) | | | | **`VisualizerOverrides`** | `concepts/viscomp-visualizer-override` | Override a visualizer | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/viscomp-visualizer-override.py) | | | | **`VisualizerOverrides`** | `concepts/viscomp-visualizer-override-multiple` | Override a visualizer | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/viscomp-visualizer-override-multiple.py) | | | diff --git a/examples/python/graph_lattice/README.md b/examples/python/graph_lattice/README.md index a44ec2eeab8d..f6d55edcd3c9 100644 --- a/examples/python/graph_lattice/README.md +++ b/examples/python/graph_lattice/README.md @@ -17,8 +17,8 @@ Since no explicit positions are passed for the nodes, Rerun will layout the grap ## Used Rerun types -[`GraphNodes`](https://www.rerun.io/docs/reference/types/archetypes/graph_nodes?speculative-link), -[`GraphEdges`](https://www.rerun.io/docs/reference/types/archetypes/graph_edges?speculative-link) +[`GraphNodes`](https://www.rerun.io/docs/reference/types/archetypes/graph_nodes), +[`GraphEdges`](https://www.rerun.io/docs/reference/types/archetypes/graph_edges) ## Run the code diff --git a/examples/python/graph_lattice/graph_lattice.py b/examples/python/graph_lattice/graph_lattice.py index 21eb327df1ca..0df3efa1f7d3 100644 --- a/examples/python/graph_lattice/graph_lattice.py +++ b/examples/python/graph_lattice/graph_lattice.py @@ -17,7 +17,7 @@ In this example, the node positionsβ€”and therefore the graph layoutβ€”are computed by Rerun internally. The full source code for this example is available -[on GitHub](https://github.com/rerun-io/rerun/blob/latest/examples/python/graph_lattice?speculative-link). +[on GitHub](https://github.com/rerun-io/rerun/blob/latest/examples/python/graph_lattice). """.strip() diff --git a/examples/python/graphs/README.md b/examples/python/graphs/README.md index b06d813bd166..2d855c9cb919 100644 --- a/examples/python/graphs/README.md +++ b/examples/python/graphs/README.md @@ -25,8 +25,8 @@ This example shows different types of layouts: ## Used Rerun types -[`GraphNodes`](https://www.rerun.io/docs/reference/types/archetypes/graph_nodes?speculative-link), -[`GraphEdges`](https://www.rerun.io/docs/reference/types/archetypes/graph_edges?speculative-link) +[`GraphNodes`](https://www.rerun.io/docs/reference/types/archetypes/graph_nodes), +[`GraphEdges`](https://www.rerun.io/docs/reference/types/archetypes/graph_edges) ## Force-based layouts diff --git a/examples/python/graphs/graphs.py b/examples/python/graphs/graphs.py index 3bf490c625d9..9b1abf9c6acc 100644 --- a/examples/python/graphs/graphs.py +++ b/examples/python/graphs/graphs.py @@ -37,7 +37,7 @@ You can modify how these graphs look by changing the parameters of the force-based layout algorithm in the selection panel. The full source code for this example is available -[on GitHub](https://github.com/rerun-io/rerun/blob/latest/examples/python/graphs?speculative-link). +[on GitHub](https://github.com/rerun-io/rerun/blob/latest/examples/python/graphs). """.strip() diff --git a/examples/rust/clock/Cargo.toml b/examples/rust/clock/Cargo.toml index 8e7862da7ed7..f898f5799c9a 100644 --- a/examples/rust/clock/Cargo.toml +++ b/examples/rust/clock/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clock" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" edition = "2021" rust-version = "1.80" license = "MIT OR Apache-2.0" diff --git a/examples/rust/custom_data_loader/Cargo.toml b/examples/rust/custom_data_loader/Cargo.toml index a7c4699037ac..4a00a1cff0fa 100644 --- a/examples/rust/custom_data_loader/Cargo.toml +++ b/examples/rust/custom_data_loader/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "custom_data_loader" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" edition = "2021" rust-version = "1.80" license = "MIT OR Apache-2.0" diff --git a/examples/rust/custom_store_subscriber/Cargo.toml b/examples/rust/custom_store_subscriber/Cargo.toml index 654d3353575c..28459d89f65b 100644 --- a/examples/rust/custom_store_subscriber/Cargo.toml +++ b/examples/rust/custom_store_subscriber/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "custom_store_subscriber" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" edition = "2021" rust-version = "1.80" license = "MIT OR Apache-2.0" diff --git a/examples/rust/custom_view/Cargo.toml b/examples/rust/custom_view/Cargo.toml index 31818d428102..7babb2fd3a6b 100644 --- a/examples/rust/custom_view/Cargo.toml +++ b/examples/rust/custom_view/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "custom_view" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" edition = "2021" rust-version = "1.80" license = "MIT OR Apache-2.0" diff --git a/examples/rust/dataframe_query/Cargo.toml b/examples/rust/dataframe_query/Cargo.toml index 538b9047d8aa..51a4d872112d 100644 --- a/examples/rust/dataframe_query/Cargo.toml +++ b/examples/rust/dataframe_query/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "dataframe_query" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" edition = "2021" rust-version = "1.80" license = "MIT OR Apache-2.0" diff --git a/examples/rust/dna/Cargo.toml b/examples/rust/dna/Cargo.toml index 21dec7a03ced..04e456883df9 100644 --- a/examples/rust/dna/Cargo.toml +++ b/examples/rust/dna/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "dna" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" edition = "2021" rust-version = "1.80" license = "MIT OR Apache-2.0" diff --git a/examples/rust/extend_viewer_ui/Cargo.toml b/examples/rust/extend_viewer_ui/Cargo.toml index 6e4a385aa850..29dd7233a6ce 100644 --- a/examples/rust/extend_viewer_ui/Cargo.toml +++ b/examples/rust/extend_viewer_ui/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "extend_viewer_ui" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" edition = "2021" rust-version = "1.80" license = "MIT OR Apache-2.0" diff --git a/examples/rust/external_data_loader/Cargo.toml b/examples/rust/external_data_loader/Cargo.toml index 956a9c949d0c..53101d926ba6 100644 --- a/examples/rust/external_data_loader/Cargo.toml +++ b/examples/rust/external_data_loader/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rerun-loader-rust-file" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" edition = "2021" rust-version = "1.80" license = "MIT OR Apache-2.0" diff --git a/examples/rust/graph_lattice/Cargo.toml b/examples/rust/graph_lattice/Cargo.toml index b0c602c619e7..88bb40f03e1f 100644 --- a/examples/rust/graph_lattice/Cargo.toml +++ b/examples/rust/graph_lattice/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "graph_lattice" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" edition = "2021" rust-version = "1.80" license = "MIT OR Apache-2.0" diff --git a/examples/rust/graph_lattice/README.md b/examples/rust/graph_lattice/README.md index 0f3e4ea460f9..eaddac3f256d 100644 --- a/examples/rust/graph_lattice/README.md +++ b/examples/rust/graph_lattice/README.md @@ -17,8 +17,8 @@ Since no explicit positions are passed for the nodes, Rerun will layout the grap ## Used Rerun types -[`GraphNodes`](https://www.rerun.io/docs/reference/types/archetypes/graph_nodes?speculative-link), -[`GraphEdges`](https://www.rerun.io/docs/reference/types/archetypes/graph_edges?speculative-link) +[`GraphNodes`](https://www.rerun.io/docs/reference/types/archetypes/graph_nodes), +[`GraphEdges`](https://www.rerun.io/docs/reference/types/archetypes/graph_edges) ## Run the code diff --git a/examples/rust/incremental_logging/Cargo.toml b/examples/rust/incremental_logging/Cargo.toml index 16d0e2c8dcfd..b02487a8ee2a 100644 --- a/examples/rust/incremental_logging/Cargo.toml +++ b/examples/rust/incremental_logging/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "incremental_logging" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" edition = "2021" rust-version = "1.80" license = "MIT OR Apache-2.0" diff --git a/examples/rust/log_file/Cargo.toml b/examples/rust/log_file/Cargo.toml index 61efa8c61bdb..7cb0ea0b2ba4 100644 --- a/examples/rust/log_file/Cargo.toml +++ b/examples/rust/log_file/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "log_file" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" edition = "2021" rust-version = "1.80" license = "MIT OR Apache-2.0" diff --git a/examples/rust/minimal/Cargo.toml b/examples/rust/minimal/Cargo.toml index fa1574b3c4cb..c8ec25baf7e1 100644 --- a/examples/rust/minimal/Cargo.toml +++ b/examples/rust/minimal/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "minimal" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" edition = "2021" rust-version = "1.80" license = "MIT OR Apache-2.0" diff --git a/examples/rust/minimal_options/Cargo.toml b/examples/rust/minimal_options/Cargo.toml index 12aeb3549093..25fe7f825524 100644 --- a/examples/rust/minimal_options/Cargo.toml +++ b/examples/rust/minimal_options/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "minimal_options" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" edition = "2021" rust-version = "1.80" license = "MIT OR Apache-2.0" diff --git a/examples/rust/minimal_serve/Cargo.toml b/examples/rust/minimal_serve/Cargo.toml index cc9b36b7eaab..b420921c429d 100644 --- a/examples/rust/minimal_serve/Cargo.toml +++ b/examples/rust/minimal_serve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "minimal_serve" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" edition = "2021" rust-version = "1.80" license = "MIT OR Apache-2.0" diff --git a/examples/rust/objectron/Cargo.toml b/examples/rust/objectron/Cargo.toml index 201a3218a7e8..9c194bf914f1 100644 --- a/examples/rust/objectron/Cargo.toml +++ b/examples/rust/objectron/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "objectron" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" edition = "2021" rust-version = "1.80" license = "MIT OR Apache-2.0" diff --git a/examples/rust/raw_mesh/Cargo.toml b/examples/rust/raw_mesh/Cargo.toml index 051b612e2275..f39273d5d9ee 100644 --- a/examples/rust/raw_mesh/Cargo.toml +++ b/examples/rust/raw_mesh/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "raw_mesh" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" edition = "2021" rust-version = "1.80" license = "MIT OR Apache-2.0" diff --git a/examples/rust/shared_recording/Cargo.toml b/examples/rust/shared_recording/Cargo.toml index ba713863611f..cc254dd4db72 100644 --- a/examples/rust/shared_recording/Cargo.toml +++ b/examples/rust/shared_recording/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "shared_recording" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" edition = "2021" rust-version = "1.80" license = "MIT OR Apache-2.0" diff --git a/examples/rust/spawn_viewer/Cargo.toml b/examples/rust/spawn_viewer/Cargo.toml index 050cc9655af5..b35b9af9876b 100644 --- a/examples/rust/spawn_viewer/Cargo.toml +++ b/examples/rust/spawn_viewer/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "spawn_viewer" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" edition = "2021" rust-version = "1.80" license = "MIT OR Apache-2.0" diff --git a/examples/rust/stdio/Cargo.toml b/examples/rust/stdio/Cargo.toml index 285564d8bc2f..9a410b830cdb 100644 --- a/examples/rust/stdio/Cargo.toml +++ b/examples/rust/stdio/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "stdio" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" edition = "2021" rust-version = "1.80" license = "MIT OR Apache-2.0" diff --git a/examples/rust/template/Cargo.toml b/examples/rust/template/Cargo.toml index 2876785083e5..61932c222612 100644 --- a/examples/rust/template/Cargo.toml +++ b/examples/rust/template/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "template" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" edition = "2021" rust-version = "1.80" license = "MIT OR Apache-2.0" diff --git a/pixi.lock b/pixi.lock index 704ab17f98a4..ad8fed5b1757 100644 --- a/pixi.lock +++ b/pixi.lock @@ -30286,8 +30286,8 @@ packages: - watchfiles ; extra == 'dev' - pypi: rerun_notebook name: rerun-notebook - version: 0.21.0a1+dev - sha256: 047bf251505a9b46f02e7f700fe4073247fa2c95f8dd36f6f2f628e0ade8c055 + version: 0.22.0a1+dev + sha256: 7e12a38063373d2b82c7eb731a3985d7646c0ecd59b5c6230a8a48955094b723 requires_dist: - anywidget - jupyter-ui-poll @@ -30362,8 +30362,8 @@ packages: requires_python: '>=3.8,<3.13' - pypi: rerun_py name: rerun-sdk - version: 0.21.0a1+dev - sha256: a2a848bd650eb5075582955b9dfcb9e4e43a5d1209ca7f053ceeed16ded0118a + version: 0.22.0a1+dev + sha256: 4a0b3da14f4aef104a2c3c4c8db24f35528b5b96590c282a5e52d53a96aea177 requires_dist: - attrs>=23.1.0 - numpy>=1.23 @@ -30371,7 +30371,7 @@ packages: - pyarrow>=14.0.2 - typing-extensions>=4.5 - pytest==7.1.2 ; extra == 'tests' - - rerun-notebook==0.21.0a1+dev ; extra == 'notebook' + - rerun-notebook==0.22.0a1+dev ; extra == 'notebook' requires_python: '>=3.8' editable: true - pypi: https://files.pythonhosted.org/packages/7b/44/4e421b96b67b2daff264473f7465db72fbdf36a07e05494f50300cc7b0c6/rfc3339_validator-0.1.4-py2.py3-none-any.whl diff --git a/rerun_cpp/src/rerun/archetypes/ellipsoids3d.hpp b/rerun_cpp/src/rerun/archetypes/ellipsoids3d.hpp index b65fbb6419ee..b84f7c317287 100644 --- a/rerun_cpp/src/rerun/archetypes/ellipsoids3d.hpp +++ b/rerun_cpp/src/rerun/archetypes/ellipsoids3d.hpp @@ -34,6 +34,61 @@ namespace rerun::archetypes { /// Note that orienting and placing the ellipsoids/spheres is handled via `[archetypes.InstancePoses3D]`. /// Some of its component are repeated here for convenience. /// If there's more instance poses than half sizes, the last half size will be repeated for the remaining poses. + /// + /// ## Example + /// + /// ### Covariance ellipsoid + /// ![image](https://static.rerun.io/elliopsoid3d_simple/bd5d46e61b80ae44792b52ee07d750a7137002ea/full.png) + /// + /// ```cpp + /// #include + /// + /// #include + /// #include + /// #include + /// + /// int main() { + /// const auto rec = rerun::RecordingStream("rerun_example_ellipsoid_simple"); + /// rec.spawn().exit_on_failure(); + /// + /// const float sigmas[3] = {5.0f, 3.0f, 1.0f}; + /// + /// std::default_random_engine gen; + /// std::normal_distribution dist(0.0, 1.0f); + /// + /// std::vector points3d(50000); + /// std::generate(points3d.begin(), points3d.end(), [&] { + /// return rerun::Position3D( + /// sigmas[0] * dist(gen), + /// sigmas[1] * dist(gen), + /// sigmas[2] * dist(gen) + /// ); + /// }); + /// + /// rec.log( + /// "points", + /// rerun::Points3D(points3d).with_radii(0.02f).with_colors(rerun::Rgba32(188, 77, 185)) + /// ); + /// + /// rec.log( + /// "ellipsoid", + /// rerun::Ellipsoids3D::from_centers_and_half_sizes( + /// { + /// {0.0f, 0.0f, 0.0f}, + /// {0.0f, 0.0f, 0.0f}, + /// }, + /// { + /// {sigmas[0], sigmas[1], sigmas[2]}, + /// {3.0f * sigmas[0], 3.0f * sigmas[1], 3.0f * sigmas[2]}, + /// } + /// ) + /// .with_colors({ + /// rerun::Rgba32(255, 255, 0), + /// rerun::Rgba32(64, 64, 0), + /// }) + /// ); + /// } + /// ``` struct Ellipsoids3D { /// For each ellipsoid, half of its size on its three axes. /// diff --git a/rerun_cpp/src/rerun/archetypes/graph_edges.hpp b/rerun_cpp/src/rerun/archetypes/graph_edges.hpp index a19940a3a351..7ae79b0a58b6 100644 --- a/rerun_cpp/src/rerun/archetypes/graph_edges.hpp +++ b/rerun_cpp/src/rerun/archetypes/graph_edges.hpp @@ -44,8 +44,6 @@ namespace rerun::archetypes { /// ); /// } /// ``` - /// - /// ⚠ **This is an experimental API! It is not fully supported, and is likely to change significantly in future versions.** struct GraphEdges { /// A list of node tuples. Collection edges; diff --git a/rerun_cpp/src/rerun/archetypes/graph_nodes.hpp b/rerun_cpp/src/rerun/archetypes/graph_nodes.hpp index 3ee519b9e729..6017a265a565 100644 --- a/rerun_cpp/src/rerun/archetypes/graph_nodes.hpp +++ b/rerun_cpp/src/rerun/archetypes/graph_nodes.hpp @@ -46,8 +46,6 @@ namespace rerun::archetypes { /// ); /// } /// ``` - /// - /// ⚠ **This is an experimental API! It is not fully supported, and is likely to change significantly in future versions.** struct GraphNodes { /// A list of node IDs. Collection node_ids; diff --git a/rerun_cpp/src/rerun/c/sdk_info.h b/rerun_cpp/src/rerun/c/sdk_info.h index d1e864f0498e..eb36492072a9 100644 --- a/rerun_cpp/src/rerun/c/sdk_info.h +++ b/rerun_cpp/src/rerun/c/sdk_info.h @@ -2,13 +2,13 @@ /// /// This should match the string returned by `rr_version_string` (C) or `rerun::version_string` (C++). /// If not, the SDK's binary and the C header are out of sync. -#define RERUN_SDK_HEADER_VERSION "0.21.0-alpha.1+dev" +#define RERUN_SDK_HEADER_VERSION "0.22.0-alpha.1+dev" /// Major version of the Rerun C SDK. #define RERUN_SDK_HEADER_VERSION_MAJOR 0 /// Minor version of the Rerun C SDK. -#define RERUN_SDK_HEADER_VERSION_MINOR 21 +#define RERUN_SDK_HEADER_VERSION_MINOR 22 /// Patch version of the Rerun C SDK. #define RERUN_SDK_HEADER_VERSION_PATCH 0 diff --git a/rerun_js/web-viewer-react/README.md b/rerun_js/web-viewer-react/README.md index 361b1d63f155..3b569a57ea11 100644 --- a/rerun_js/web-viewer-react/README.md +++ b/rerun_js/web-viewer-react/README.md @@ -35,7 +35,7 @@ export default function App() { ``` The `rrd` in the snippet above should be a URL pointing to either: -- A hosted `.rrd` file, such as +- A hosted `.rrd` file, such as - A WebSocket connection to the SDK opened via the [`serve`](https://www.rerun.io/docs/reference/sdk/operating-modes#serve) API If `rrd` is not set, the Viewer will display the same welcome screen as . diff --git a/rerun_js/web-viewer-react/package.json b/rerun_js/web-viewer-react/package.json index a3f9eb5734a1..2b296ea8b714 100644 --- a/rerun_js/web-viewer-react/package.json +++ b/rerun_js/web-viewer-react/package.json @@ -1,6 +1,6 @@ { "name": "@rerun-io/web-viewer-react", - "version": "0.21.0-alpha.1+dev", + "version": "0.22.0-alpha.1+dev", "description": "Embed the Rerun web viewer in your React app", "licenses": [ { @@ -39,7 +39,7 @@ "tsconfig.json" ], "dependencies": { - "@rerun-io/web-viewer": "0.21.0-alpha.1", + "@rerun-io/web-viewer": "0.22.0-alpha.1", "@types/react": "^18.2.33", "react": "^18.2.0" }, diff --git a/rerun_js/web-viewer/README.md b/rerun_js/web-viewer/README.md index 7b714f3915a6..a9f0609f49e5 100644 --- a/rerun_js/web-viewer/README.md +++ b/rerun_js/web-viewer/README.md @@ -41,7 +41,7 @@ viewer.stop(); ``` The `rrd` in the snippet above should be a URL pointing to either: -- A hosted `.rrd` file, such as +- A hosted `.rrd` file, such as - A WebSocket connection to the SDK opened via the [`serve`](https://www.rerun.io/docs/reference/sdk/operating-modes#serve) API If `rrd` is not set, the Viewer will display the same welcome screen as . diff --git a/rerun_js/web-viewer/package.json b/rerun_js/web-viewer/package.json index 4da306e5c0a6..2ee11bf4a1dd 100644 --- a/rerun_js/web-viewer/package.json +++ b/rerun_js/web-viewer/package.json @@ -1,6 +1,6 @@ { "name": "@rerun-io/web-viewer", - "version": "0.21.0-alpha.1+dev", + "version": "0.22.0-alpha.1+dev", "description": "Embed the Rerun web viewer in your app", "licenses": [ { diff --git a/rerun_notebook/pyproject.toml b/rerun_notebook/pyproject.toml index 52105c2c8d55..23ae9bdd7ae0 100644 --- a/rerun_notebook/pyproject.toml +++ b/rerun_notebook/pyproject.toml @@ -5,7 +5,7 @@ build-backend = "hatchling.build" [project] name = "rerun-notebook" description = "Implementation helper for running rerun-sdk in notebooks" -version = "0.21.0-alpha.1+dev" +version = "0.22.0-alpha.1+dev" dependencies = ["anywidget", "jupyter-ui-poll"] readme = "README.md" keywords = ["rerun", "notebook"] diff --git a/rerun_py/pyproject.toml b/rerun_py/pyproject.toml index fb430c0a825f..7c67fc68b6b0 100644 --- a/rerun_py/pyproject.toml +++ b/rerun_py/pyproject.toml @@ -33,7 +33,7 @@ text = "MIT OR Apache-2.0" [project.optional-dependencies] tests = ["pytest==7.1.2"] -notebook = ["rerun-notebook==0.21.0-alpha.1+dev"] +notebook = ["rerun-notebook==0.22.0-alpha.1+dev"] [project.urls] documentation = "https://www.rerun.io/docs" diff --git a/rerun_py/rerun_sdk/rerun/__init__.py b/rerun_py/rerun_sdk/rerun/__init__.py index ffa7ac282107..f396868fbd8e 100644 --- a/rerun_py/rerun_sdk/rerun/__init__.py +++ b/rerun_py/rerun_sdk/rerun/__init__.py @@ -9,8 +9,8 @@ import numpy as np -__version__ = "0.21.0-alpha.1+dev" -__version_info__ = (0, 21, 0, "alpha.1") +__version__ = "0.22.0-alpha.1+dev" +__version_info__ = (0, 22, 0, "alpha.1") if sys.version_info < (3, 9): warnings.warn( diff --git a/rerun_py/rerun_sdk/rerun/archetypes/ellipsoids3d.py b/rerun_py/rerun_sdk/rerun/archetypes/ellipsoids3d.py index 0b8b6b679faa..d96015a93802 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/ellipsoids3d.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/ellipsoids3d.py @@ -28,6 +28,40 @@ class Ellipsoids3D(Ellipsoids3DExt, Archetype): Note that orienting and placing the ellipsoids/spheres is handled via `[archetypes.InstancePoses3D]`. Some of its component are repeated here for convenience. If there's more instance poses than half sizes, the last half size will be repeated for the remaining poses. + + Example + ------- + ### Covariance ellipsoid: + ```python + import numpy as np + import rerun as rr + + rr.init("rerun_example_ellipsoid_simple", spawn=True) + + center = np.array([0, 0, 0]) + sigmas = np.array([5, 3, 1]) + points = np.random.randn(50_000, 3) * sigmas.reshape(1, -1) + + rr.log("points", rr.Points3D(points, radii=0.02, colors=[188, 77, 185])) + rr.log( + "ellipsoid", + rr.Ellipsoids3D( + centers=[center, center], + half_sizes=[sigmas, 3 * sigmas], + colors=[[255, 255, 0], [64, 64, 0]], + ), + ) + ``` +
+ + + + + + + +
+ """ # __init__ can be found in ellipsoids3d_ext.py diff --git a/rerun_py/rerun_sdk/rerun/archetypes/graph_edges.py b/rerun_py/rerun_sdk/rerun/archetypes/graph_edges.py index a1568b980108..9cc648521d64 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/graph_edges.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/graph_edges.py @@ -25,8 +25,6 @@ class GraphEdges(Archetype): By default, edges are undirected. - ⚠️ **This is an experimental API! It is not fully supported, and is likely to change significantly in future versions.** - Example ------- ### Simple directed graph: diff --git a/rerun_py/rerun_sdk/rerun/archetypes/graph_nodes.py b/rerun_py/rerun_sdk/rerun/archetypes/graph_nodes.py index 13426e12ae29..ad23e270e2dc 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/graph_nodes.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/graph_nodes.py @@ -23,8 +23,6 @@ class GraphNodes(Archetype): """ **Archetype**: A list of nodes in a graph with optional labels, colors, etc. - ⚠️ **This is an experimental API! It is not fully supported, and is likely to change significantly in future versions.** - Example ------- ### Simple directed graph: diff --git a/scripts/ci/crates.py b/scripts/ci/crates.py index 89079fe39e3d..e4e818286d0a 100755 --- a/scripts/ci/crates.py +++ b/scripts/ci/crates.py @@ -434,7 +434,7 @@ def publish_crate(crate: Crate, token: str, version: str, env: dict[str, Any]) - while True: try: cargo( - f"publish --quiet --token {token}", + f"publish --quiet --locked --token {token}", cwd=crate.path, env=env, dry_run=False, diff --git a/tests/python/release_checklist/check_hover_select_reset.py b/tests/python/release_checklist/check_hover_select_reset.py index 253949bb0c7d..abcc498bac10 100644 --- a/tests/python/release_checklist/check_hover_select_reset.py +++ b/tests/python/release_checklist/check_hover_select_reset.py @@ -11,9 +11,6 @@ This checks whether different UIs behave correctly with hover and selection. -Known bugs: -* TODO(#5138): Hovering over text document views does not highlight the corresponding entity in the blueprint tree. - ### Hover For each of the views: * Hover the view and verify it shows up as highlighted in the blueprint tree. From 5a54e0899c6b30cade2f77bd2dbde04251de6bd8 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Thu, 19 Dec 2024 11:41:13 +0100 Subject: [PATCH 30/30] Update MSRV to 1.81 (#8529) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### Related * https://github.com/rerun-io/rerun/issues/7485 * #8530 ### What Update MSRV to 1.81 --------- Co-authored-by: Jochen Gârtler --- .github/workflows/nightly.yml | 2 +- BUILD.md | 4 +- Cargo.toml | 5 +- clippy.toml | 2 +- .../re_dev_tools/src/build_web_viewer/lib.rs | 2 +- crates/utils/re_analytics/src/lib.rs | 7 +- crates/utils/re_crash_handler/src/lib.rs | 107 +++++++++--------- crates/viewer/re_ui/src/design_tokens.rs | 2 +- crates/viewer/re_ui/src/lib.rs | 2 +- crates/viewer/re_view_graph/src/graph/mod.rs | 19 +--- .../re_view_graph/src/layout/geometry.rs | 2 + .../viewer/re_view_graph/src/layout/result.rs | 1 + crates/viewer/re_view_graph/src/ui/state.rs | 4 - .../re_view_graph/src/visualizers/nodes.rs | 2 - crates/viewer/re_view_tensor/src/lib.rs | 2 + .../data/quick_start_guides/rust_connect.md | 2 +- .../data/quick_start_guides/rust_spawn.md | 2 +- .../getting-started/installing-viewer.md | 2 +- .../getting-started/quick-start/rust.md | 2 +- examples/rust/clock/Cargo.toml | 2 +- examples/rust/custom_data_loader/Cargo.toml | 2 +- .../rust/custom_store_subscriber/Cargo.toml | 2 +- examples/rust/custom_view/Cargo.toml | 2 +- examples/rust/dataframe_query/Cargo.toml | 2 +- examples/rust/dna/Cargo.toml | 2 +- examples/rust/extend_viewer_ui/Cargo.toml | 2 +- examples/rust/external_data_loader/Cargo.toml | 2 +- examples/rust/graph_lattice/Cargo.toml | 2 +- examples/rust/incremental_logging/Cargo.toml | 2 +- examples/rust/log_file/Cargo.toml | 2 +- examples/rust/minimal/Cargo.toml | 2 +- examples/rust/minimal_options/Cargo.toml | 2 +- examples/rust/minimal_serve/Cargo.toml | 2 +- examples/rust/objectron/Cargo.toml | 2 +- examples/rust/raw_mesh/Cargo.toml | 2 +- examples/rust/shared_recording/Cargo.toml | 2 +- examples/rust/spawn_viewer/Cargo.toml | 2 +- examples/rust/stdio/Cargo.toml | 2 +- examples/rust/template/Cargo.toml | 2 +- rust-toolchain | 2 +- scripts/check_env.py | 4 +- scripts/clippy_wasm/clippy.toml | 2 +- scripts/lint.py | 2 +- 43 files changed, 106 insertions(+), 115 deletions(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index aa6e28f7f917..651a0af550b2 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -62,7 +62,7 @@ jobs: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@master with: - toolchain: 1.80.0 + toolchain: 1.81.0 - run: cargo build -p rerun diff --git a/BUILD.md b/BUILD.md index 24aa759a8fe3..161679017155 100644 --- a/BUILD.md +++ b/BUILD.md @@ -23,12 +23,12 @@ cd rerun Now install the `pixi` package manager: -Make sure `cargo --version` prints `1.80.0` once you are done. +Make sure `cargo --version` prints `1.81.0` once you are done. If you are using an Apple-silicon Mac (M1, M2), make sure `rustc -vV` outputs `host: aarch64-apple-darwin`. If not, this should fix it: ```sh -rustup set default-host aarch64-apple-darwin && rustup install 1.80.0 +rustup set default-host aarch64-apple-darwin && rustup install 1.81.0 ``` ## Git-lfs diff --git a/Cargo.toml b/Cargo.toml index eb00eb01b02a..3b001f0d8032 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,7 +30,7 @@ include = [ ] license = "MIT OR Apache-2.0" repository = "https://github.com/rerun-io/rerun" -rust-version = "1.80" +rust-version = "1.81" version = "0.22.0-alpha.1+dev" [workspace.dependencies] @@ -383,6 +383,7 @@ rust_2021_prelude_collisions = "warn" semicolon_in_expressions_from_macros = "warn" trivial_numeric_casts = "warn" unsafe_op_in_unsafe_fn = "warn" # `unsafe_op_in_unsafe_fn` may become the default in future Rust versions: https://github.com/rust-lang/rust/issues/71668 +unexpected_cfgs = "deny" unused_extern_crates = "warn" unused_import_braces = "warn" unused_lifetimes = "warn" @@ -467,7 +468,6 @@ match_same_arms = "warn" match_wild_err_arm = "warn" match_wildcard_for_single_variants = "warn" mem_forget = "warn" -mismatched_target_os = "warn" mismatching_type_param_order = "warn" missing_enforced_import_renames = "warn" missing_safety_doc = "warn" @@ -496,6 +496,7 @@ ref_option_ref = "warn" rest_pat_in_fully_bound_structs = "warn" same_functions_in_if_condition = "warn" semicolon_if_nothing_returned = "warn" +set_contains_or_insert = "warn" should_panic_without_expect = "warn" single_char_pattern = "warn" single_match_else = "warn" diff --git a/clippy.toml b/clippy.toml index b9f05c287f9e..ec39e9871d72 100644 --- a/clippy.toml +++ b/clippy.toml @@ -3,7 +3,7 @@ # ----------------------------------------------------------------------------- # Section identical to the main scripts/clippy_wasm/clippy.toml: -msrv = "1.80" +msrv = "1.81" allow-unwrap-in-tests = true diff --git a/crates/build/re_dev_tools/src/build_web_viewer/lib.rs b/crates/build/re_dev_tools/src/build_web_viewer/lib.rs index 3a0973bc56bc..8fa7c622d433 100644 --- a/crates/build/re_dev_tools/src/build_web_viewer/lib.rs +++ b/crates/build/re_dev_tools/src/build_web_viewer/lib.rs @@ -124,7 +124,7 @@ pub fn build( cmd.arg("--no-default-features"); } if !features.is_empty() { - cmd.arg(&format!("--features={features}")); + cmd.arg(format!("--features={features}")); } if profile == Profile::Release { cmd.arg("--release"); diff --git a/crates/utils/re_analytics/src/lib.rs b/crates/utils/re_analytics/src/lib.rs index a0a10c8e7b0d..709f08f27345 100644 --- a/crates/utils/re_analytics/src/lib.rs +++ b/crates/utils/re_analytics/src/lib.rs @@ -217,12 +217,13 @@ pub struct Analytics { fn load_config() -> Result { let config = match Config::load() { Ok(config) => config, - #[allow(unused_variables)] + Err(err) => { // NOTE: This will cause the first run disclaimer to show up again on native, // and analytics will be disabled for the rest of the session. - #[cfg(not(target_arch = "wasm32"))] - re_log::warn!("failed to load analytics config file: {err}"); + if !cfg!(target_arch = "wasm32") { + re_log::warn!("failed to load analytics config file: {err}"); + } None } }; diff --git a/crates/utils/re_crash_handler/src/lib.rs b/crates/utils/re_crash_handler/src/lib.rs index 9efe2c28aa69..781954fb971b 100644 --- a/crates/utils/re_crash_handler/src/lib.rs +++ b/crates/utils/re_crash_handler/src/lib.rs @@ -28,69 +28,72 @@ pub fn install_crash_handlers(build_info: BuildInfo) { fn install_panic_hook(_build_info: BuildInfo) { let previous_panic_hook = std::panic::take_hook(); - std::panic::set_hook(Box::new(move |panic_info: &std::panic::PanicInfo<'_>| { - let callstack = callstack_from(&["panicking::panic_fmt\n"]); - - let file_line = panic_info.location().map(|location| { - let file = anonymize_source_file_path(&std::path::PathBuf::from(location.file())); - format!("{file}:{}", location.line()) - }); - - let msg = panic_info_message(panic_info); - - if let Some(msg) = &msg { - // Print our own panic message. - // Our formatting is nicer than `std` since we shorten the file paths (for privacy reasons). - // This also makes it easier for users to copy-paste the callstack into an issue - // without having any sensitive data in it. - - let thread = std::thread::current(); - let thread_name = thread - .name() - .map_or_else(|| format!("{:?}", thread.id()), |name| name.to_owned()); - - eprintln!("\nthread '{thread_name}' panicked at '{msg}'"); - if let Some(file_line) = &file_line { - eprintln!("{file_line}"); + std::panic::set_hook(Box::new( + move |panic_info: &std::panic::PanicHookInfo<'_>| { + let callstack = callstack_from(&["panicking::panic_fmt\n"]); + + let file_line = panic_info.location().map(|location| { + let file = anonymize_source_file_path(&std::path::PathBuf::from(location.file())); + format!("{file}:{}", location.line()) + }); + + let msg = panic_info_message(panic_info); + + if let Some(msg) = &msg { + // Print our own panic message. + // Our formatting is nicer than `std` since we shorten the file paths (for privacy reasons). + // This also makes it easier for users to copy-paste the callstack into an issue + // without having any sensitive data in it. + + let thread = std::thread::current(); + let thread_name = thread + .name() + .map_or_else(|| format!("{:?}", thread.id()), |name| name.to_owned()); + + eprintln!("\nthread '{thread_name}' panicked at '{msg}'"); + if let Some(file_line) = &file_line { + eprintln!("{file_line}"); + } + eprintln!("stack backtrace:\n{callstack}"); + } else { + // This prints the panic message and callstack: + (*previous_panic_hook)(panic_info); } - eprintln!("stack backtrace:\n{callstack}"); - } else { - // This prints the panic message and callstack: - (*previous_panic_hook)(panic_info); - } - econtext::print_econtext(); // Print additional error context, if any + econtext::print_econtext(); // Print additional error context, if any - eprintln!( - "\n\ + eprintln!( + "\n\ Troubleshooting Rerun: https://www.rerun.io/docs/getting-started/troubleshooting \n\ Report bugs: https://github.com/rerun-io/rerun/issues" - ); + ); - #[cfg(feature = "analytics")] - { - if let Ok(analytics) = re_analytics::Analytics::new(std::time::Duration::from_millis(1)) + #[cfg(feature = "analytics")] { - analytics.record(re_analytics::event::CrashPanic { - build_info: _build_info, - callstack, - // Don't include panic message, because it can contain sensitive information, - // e.g. `panic!("Couldn't read {sensitive_file_path}")`. - message: None, - file_line, - }); - - std::thread::sleep(std::time::Duration::from_secs(1)); // Give analytics time to send the event + if let Ok(analytics) = + re_analytics::Analytics::new(std::time::Duration::from_millis(1)) + { + analytics.record(re_analytics::event::CrashPanic { + build_info: _build_info, + callstack, + // Don't include panic message, because it can contain sensitive information, + // e.g. `panic!("Couldn't read {sensitive_file_path}")`. + message: None, + file_line, + }); + + std::thread::sleep(std::time::Duration::from_secs(1)); // Give analytics time to send the event + } } - } - // We compile with `panic = "abort"`, but we don't want to report the same problem twice, so just exit: - #[allow(clippy::exit)] - std::process::exit(102); - })); + // We compile with `panic = "abort"`, but we don't want to report the same problem twice, so just exit: + #[allow(clippy::exit)] + std::process::exit(102); + }, + )); } -fn panic_info_message(panic_info: &std::panic::PanicInfo<'_>) -> Option { +fn panic_info_message(panic_info: &std::panic::PanicHookInfo<'_>) -> Option { // `panic_info.message` is unstable, so this is the recommended way of getting // the panic message out. We need both the `&str` and `String` variants. diff --git a/crates/viewer/re_ui/src/design_tokens.rs b/crates/viewer/re_ui/src/design_tokens.rs index 125e64989d93..aa740ce30da4 100644 --- a/crates/viewer/re_ui/src/design_tokens.rs +++ b/crates/viewer/re_ui/src/design_tokens.rs @@ -15,7 +15,7 @@ pub struct DesignTokens { /// Color table for all colors used in the UI. /// /// Loaded at startup from `design_tokens.json`. - color_table: ColorTable, + pub color_table: ColorTable, // TODO(ab): get rid of these, they should be function calls like the rest. pub top_bar_color: egui::Color32, diff --git a/crates/viewer/re_ui/src/lib.rs b/crates/viewer/re_ui/src/lib.rs index 3bbc851676fb..ba9b22dbfa33 100644 --- a/crates/viewer/re_ui/src/lib.rs +++ b/crates/viewer/re_ui/src/lib.rs @@ -19,7 +19,7 @@ pub mod zoom_pan_area; use egui::NumExt as _; pub use self::{ - color_table::{ColorToken, Hue, Scale}, + color_table::{ColorTable, ColorToken, Hue, Scale}, command::{UICommand, UICommandSender}, command_palette::CommandPalette, context_ext::ContextExt, diff --git a/crates/viewer/re_view_graph/src/graph/mod.rs b/crates/viewer/re_view_graph/src/graph/mod.rs index 4ddb4c969087..35f5c5f43750 100644 --- a/crates/viewer/re_view_graph/src/graph/mod.rs +++ b/crates/viewer/re_view_graph/src/graph/mod.rs @@ -48,14 +48,6 @@ impl Node { } } - /// The original [`components::GraphNode`] id that was logged by the user. - pub fn graph_node(&self) -> &components::GraphNode { - match self { - Self::Explicit { instance, .. } => &instance.graph_node, - Self::Implicit { graph_node, .. } => graph_node, - } - } - pub fn label(&self) -> &DrawableLabel { match self { Self::Explicit { label, .. } | Self::Implicit { label, .. } => label, @@ -81,6 +73,7 @@ pub struct Graph { entity: EntityPath, nodes: Vec, edges: Vec, + #[expect(unused)] kind: GraphType, } @@ -110,21 +103,19 @@ impl Graph { let (edges, kind) = if let Some(data) = edge_data { for edge in &data.edges { - if !seen.contains(&edge.source_index) { + if seen.insert(edge.source_index) { nodes.push(Node::Implicit { id: edge.source_index, graph_node: edge.source.clone(), label: DrawableLabel::implicit_circle(ui), }); - seen.insert(edge.source_index); } - if !seen.contains(&edge.target_index) { + if seen.insert(edge.target_index) { nodes.push(Node::Implicit { id: edge.target_index, graph_node: edge.target.clone(), label: DrawableLabel::implicit_circle(ui), }); - seen.insert(edge.target_index); } } @@ -155,10 +146,6 @@ impl Graph { &self.edges } - pub fn kind(&self) -> GraphType { - self.kind - } - pub fn entity(&self) -> &EntityPath { &self.entity } diff --git a/crates/viewer/re_view_graph/src/layout/geometry.rs b/crates/viewer/re_view_graph/src/layout/geometry.rs index 52498c900049..0a8e2d306d19 100644 --- a/crates/viewer/re_view_graph/src/layout/geometry.rs +++ b/crates/viewer/re_view_graph/src/layout/geometry.rs @@ -39,6 +39,7 @@ impl EdgeGeometry { } /// The starting position of an edge. + #[expect(unused)] pub fn source_pos(&self) -> Pos2 { match self.path { PathGeometry::Line { source, .. } | PathGeometry::CubicBezier { source, .. } => source, @@ -53,6 +54,7 @@ impl EdgeGeometry { } /// The direction of the edge at the source node (normalized). + #[expect(unused)] pub fn source_arrow_direction(&self) -> Vec2 { use PathGeometry::{CubicBezier, Line}; match self.path { diff --git a/crates/viewer/re_view_graph/src/layout/result.rs b/crates/viewer/re_view_graph/src/layout/result.rs index 85c03a5d33fb..7ed15553187b 100644 --- a/crates/viewer/re_view_graph/src/layout/result.rs +++ b/crates/viewer/re_view_graph/src/layout/result.rs @@ -41,6 +41,7 @@ impl Layout { } /// Gets the shape of an edge in the final layout. + #[expect(unused)] pub fn get_edge(&self, edge: &EdgeId) -> Option<&[EdgeGeometry]> { self.edges.get(edge).map(|es| es.as_slice()) } diff --git a/crates/viewer/re_view_graph/src/ui/state.rs b/crates/viewer/re_view_graph/src/ui/state.rs index e15ec96afb3c..79c0221174e0 100644 --- a/crates/viewer/re_view_graph/src/ui/state.rs +++ b/crates/viewer/re_view_graph/src/ui/state.rs @@ -82,10 +82,6 @@ impl LayoutState { *self = Self::None; } - pub fn is_none(&self) -> bool { - matches!(self, Self::None) - } - pub fn is_in_progress(&self) -> bool { matches!(self, Self::InProgress { .. }) } diff --git a/crates/viewer/re_view_graph/src/visualizers/nodes.rs b/crates/viewer/re_view_graph/src/visualizers/nodes.rs index b03a0c3121f6..d65e45f15c6f 100644 --- a/crates/viewer/re_view_graph/src/visualizers/nodes.rs +++ b/crates/viewer/re_view_graph/src/visualizers/nodes.rs @@ -41,7 +41,6 @@ pub enum Label { /// A [`NodeInstance`] is the output of the [`NodeVisualizer`] and represents a single node in the graph. #[derive(Clone)] pub struct NodeInstance { - pub graph_node: components::GraphNode, pub instance_index: Instance, pub id: NodeId, pub position: Option, @@ -128,7 +127,6 @@ impl VisualizerSystem for NodeVisualizer { }; NodeInstance { - graph_node: node.clone(), instance_index: instance, id: NodeId::from_entity_node(&data_result.entity_path, node), position: position.map(|[x, y]| egui::Pos2::new(x, y)), diff --git a/crates/viewer/re_view_tensor/src/lib.rs b/crates/viewer/re_view_tensor/src/lib.rs index 19492b29bf34..f6e913430dd0 100644 --- a/crates/viewer/re_view_tensor/src/lib.rs +++ b/crates/viewer/re_view_tensor/src/lib.rs @@ -32,10 +32,12 @@ impl TensorDimension { .collect() } + #[allow(dead_code)] // Used for tests pub fn unnamed(size: u64) -> Self { Self { size, name: None } } + #[allow(dead_code)] // Used for tests pub fn named(size: u64, name: impl Into) -> Self { Self { size, diff --git a/crates/viewer/re_viewer/data/quick_start_guides/rust_connect.md b/crates/viewer/re_viewer/data/quick_start_guides/rust_connect.md index c5b748b7772f..e3facf5f3f64 100644 --- a/crates/viewer/re_viewer/data/quick_start_guides/rust_connect.md +++ b/crates/viewer/re_viewer/data/quick_start_guides/rust_connect.md @@ -10,7 +10,7 @@ Let's try it out in a brand-new Rust project: cargo init cube && cd cube && cargo add rerun --features native_viewer ``` -Note that the Rerun SDK requires a working installation of Rust 1.80+. +Note that the Rerun SDK requires a working installation of Rust 1.81+. ## Logging your own data diff --git a/crates/viewer/re_viewer/data/quick_start_guides/rust_spawn.md b/crates/viewer/re_viewer/data/quick_start_guides/rust_spawn.md index cde772f1aad2..ae2c4aa1cddd 100644 --- a/crates/viewer/re_viewer/data/quick_start_guides/rust_spawn.md +++ b/crates/viewer/re_viewer/data/quick_start_guides/rust_spawn.md @@ -10,7 +10,7 @@ Let's try it out in a brand-new Rust project: cargo init cube && cd cube && cargo add rerun ``` -Note that the Rerun SDK requires a working installation of Rust 1.80+. +Note that the Rerun SDK requires a working installation of Rust 1.81+. ## Logging your own data diff --git a/docs/content/getting-started/installing-viewer.md b/docs/content/getting-started/installing-viewer.md index 55ebc55e8ab8..89aac23fed2b 100644 --- a/docs/content/getting-started/installing-viewer.md +++ b/docs/content/getting-started/installing-viewer.md @@ -40,7 +40,7 @@ There are many ways to install the viewer. Please pick whatever works best for y - Download `rerun-cli` for your platform from the [GitHub Release artifacts](https://github.com/rerun-io/rerun/releases/latest/). - Via Cargo - `cargo binstall rerun-cli` - download binaries via [`cargo binstall`](https://github.com/cargo-bins/cargo-binstall) - - `cargo install rerun-cli --locked` - build it from source (this requires Rust 1.80+) + - `cargo install rerun-cli --locked` - build it from source (this requires Rust 1.81+) - Together with the Rerun [Python SDK](./quick-start/python.md): - `pip3 install rerun-sdk` - download it via pip - `conda install -c conda-forge rerun-sdk` - download via Conda diff --git a/docs/content/getting-started/quick-start/rust.md b/docs/content/getting-started/quick-start/rust.md index c79bc34db7c2..69f92ff3c9ce 100644 --- a/docs/content/getting-started/quick-start/rust.md +++ b/docs/content/getting-started/quick-start/rust.md @@ -5,7 +5,7 @@ order: 3 ## Setup -The Rerun SDK for Rust requires a working installation of Rust 1.80+. +The Rerun SDK for Rust requires a working installation of Rust 1.81+. After you have [installed the viewer](../installing-viewer.md#installing-the-viewer) you can simply add [the Rerun crate](https://crates.io/crates/rerun) to your project with `cargo add rerun`. diff --git a/examples/rust/clock/Cargo.toml b/examples/rust/clock/Cargo.toml index f898f5799c9a..1d27cfce16ef 100644 --- a/examples/rust/clock/Cargo.toml +++ b/examples/rust/clock/Cargo.toml @@ -2,7 +2,7 @@ name = "clock" version = "0.22.0-alpha.1+dev" edition = "2021" -rust-version = "1.80" +rust-version = "1.81" license = "MIT OR Apache-2.0" publish = false diff --git a/examples/rust/custom_data_loader/Cargo.toml b/examples/rust/custom_data_loader/Cargo.toml index 4a00a1cff0fa..cbdf1c81a6b0 100644 --- a/examples/rust/custom_data_loader/Cargo.toml +++ b/examples/rust/custom_data_loader/Cargo.toml @@ -2,7 +2,7 @@ name = "custom_data_loader" version = "0.22.0-alpha.1+dev" edition = "2021" -rust-version = "1.80" +rust-version = "1.81" license = "MIT OR Apache-2.0" publish = false diff --git a/examples/rust/custom_store_subscriber/Cargo.toml b/examples/rust/custom_store_subscriber/Cargo.toml index 28459d89f65b..a1b110bc6c8f 100644 --- a/examples/rust/custom_store_subscriber/Cargo.toml +++ b/examples/rust/custom_store_subscriber/Cargo.toml @@ -2,7 +2,7 @@ name = "custom_store_subscriber" version = "0.22.0-alpha.1+dev" edition = "2021" -rust-version = "1.80" +rust-version = "1.81" license = "MIT OR Apache-2.0" publish = false diff --git a/examples/rust/custom_view/Cargo.toml b/examples/rust/custom_view/Cargo.toml index 7babb2fd3a6b..cc38521c6e30 100644 --- a/examples/rust/custom_view/Cargo.toml +++ b/examples/rust/custom_view/Cargo.toml @@ -2,7 +2,7 @@ name = "custom_view" version = "0.22.0-alpha.1+dev" edition = "2021" -rust-version = "1.80" +rust-version = "1.81" license = "MIT OR Apache-2.0" publish = false diff --git a/examples/rust/dataframe_query/Cargo.toml b/examples/rust/dataframe_query/Cargo.toml index 51a4d872112d..004e0a4804a6 100644 --- a/examples/rust/dataframe_query/Cargo.toml +++ b/examples/rust/dataframe_query/Cargo.toml @@ -2,7 +2,7 @@ name = "dataframe_query" version = "0.22.0-alpha.1+dev" edition = "2021" -rust-version = "1.80" +rust-version = "1.81" license = "MIT OR Apache-2.0" publish = false diff --git a/examples/rust/dna/Cargo.toml b/examples/rust/dna/Cargo.toml index 04e456883df9..8b023677ef44 100644 --- a/examples/rust/dna/Cargo.toml +++ b/examples/rust/dna/Cargo.toml @@ -2,7 +2,7 @@ name = "dna" version = "0.22.0-alpha.1+dev" edition = "2021" -rust-version = "1.80" +rust-version = "1.81" license = "MIT OR Apache-2.0" publish = false diff --git a/examples/rust/extend_viewer_ui/Cargo.toml b/examples/rust/extend_viewer_ui/Cargo.toml index 29dd7233a6ce..633cdb891f63 100644 --- a/examples/rust/extend_viewer_ui/Cargo.toml +++ b/examples/rust/extend_viewer_ui/Cargo.toml @@ -2,7 +2,7 @@ name = "extend_viewer_ui" version = "0.22.0-alpha.1+dev" edition = "2021" -rust-version = "1.80" +rust-version = "1.81" license = "MIT OR Apache-2.0" publish = false diff --git a/examples/rust/external_data_loader/Cargo.toml b/examples/rust/external_data_loader/Cargo.toml index 53101d926ba6..5eab8acb917c 100644 --- a/examples/rust/external_data_loader/Cargo.toml +++ b/examples/rust/external_data_loader/Cargo.toml @@ -2,7 +2,7 @@ name = "rerun-loader-rust-file" version = "0.22.0-alpha.1+dev" edition = "2021" -rust-version = "1.80" +rust-version = "1.81" license = "MIT OR Apache-2.0" publish = false diff --git a/examples/rust/graph_lattice/Cargo.toml b/examples/rust/graph_lattice/Cargo.toml index 88bb40f03e1f..ca476d428b9e 100644 --- a/examples/rust/graph_lattice/Cargo.toml +++ b/examples/rust/graph_lattice/Cargo.toml @@ -2,7 +2,7 @@ name = "graph_lattice" version = "0.22.0-alpha.1+dev" edition = "2021" -rust-version = "1.80" +rust-version = "1.81" license = "MIT OR Apache-2.0" publish = false diff --git a/examples/rust/incremental_logging/Cargo.toml b/examples/rust/incremental_logging/Cargo.toml index b02487a8ee2a..f23f29eb4d35 100644 --- a/examples/rust/incremental_logging/Cargo.toml +++ b/examples/rust/incremental_logging/Cargo.toml @@ -2,7 +2,7 @@ name = "incremental_logging" version = "0.22.0-alpha.1+dev" edition = "2021" -rust-version = "1.80" +rust-version = "1.81" license = "MIT OR Apache-2.0" publish = false diff --git a/examples/rust/log_file/Cargo.toml b/examples/rust/log_file/Cargo.toml index 7cb0ea0b2ba4..517929141648 100644 --- a/examples/rust/log_file/Cargo.toml +++ b/examples/rust/log_file/Cargo.toml @@ -2,7 +2,7 @@ name = "log_file" version = "0.22.0-alpha.1+dev" edition = "2021" -rust-version = "1.80" +rust-version = "1.81" license = "MIT OR Apache-2.0" publish = false diff --git a/examples/rust/minimal/Cargo.toml b/examples/rust/minimal/Cargo.toml index c8ec25baf7e1..2f42d214ca71 100644 --- a/examples/rust/minimal/Cargo.toml +++ b/examples/rust/minimal/Cargo.toml @@ -2,7 +2,7 @@ name = "minimal" version = "0.22.0-alpha.1+dev" edition = "2021" -rust-version = "1.80" +rust-version = "1.81" license = "MIT OR Apache-2.0" publish = false diff --git a/examples/rust/minimal_options/Cargo.toml b/examples/rust/minimal_options/Cargo.toml index 25fe7f825524..263afae8696b 100644 --- a/examples/rust/minimal_options/Cargo.toml +++ b/examples/rust/minimal_options/Cargo.toml @@ -2,7 +2,7 @@ name = "minimal_options" version = "0.22.0-alpha.1+dev" edition = "2021" -rust-version = "1.80" +rust-version = "1.81" license = "MIT OR Apache-2.0" publish = false diff --git a/examples/rust/minimal_serve/Cargo.toml b/examples/rust/minimal_serve/Cargo.toml index b420921c429d..323edd8656c3 100644 --- a/examples/rust/minimal_serve/Cargo.toml +++ b/examples/rust/minimal_serve/Cargo.toml @@ -2,7 +2,7 @@ name = "minimal_serve" version = "0.22.0-alpha.1+dev" edition = "2021" -rust-version = "1.80" +rust-version = "1.81" license = "MIT OR Apache-2.0" publish = false diff --git a/examples/rust/objectron/Cargo.toml b/examples/rust/objectron/Cargo.toml index 9c194bf914f1..fb1af36d4c16 100644 --- a/examples/rust/objectron/Cargo.toml +++ b/examples/rust/objectron/Cargo.toml @@ -2,7 +2,7 @@ name = "objectron" version = "0.22.0-alpha.1+dev" edition = "2021" -rust-version = "1.80" +rust-version = "1.81" license = "MIT OR Apache-2.0" publish = false diff --git a/examples/rust/raw_mesh/Cargo.toml b/examples/rust/raw_mesh/Cargo.toml index f39273d5d9ee..2e4aa045e57c 100644 --- a/examples/rust/raw_mesh/Cargo.toml +++ b/examples/rust/raw_mesh/Cargo.toml @@ -2,7 +2,7 @@ name = "raw_mesh" version = "0.22.0-alpha.1+dev" edition = "2021" -rust-version = "1.80" +rust-version = "1.81" license = "MIT OR Apache-2.0" publish = false diff --git a/examples/rust/shared_recording/Cargo.toml b/examples/rust/shared_recording/Cargo.toml index cc254dd4db72..d892dade3bb2 100644 --- a/examples/rust/shared_recording/Cargo.toml +++ b/examples/rust/shared_recording/Cargo.toml @@ -2,7 +2,7 @@ name = "shared_recording" version = "0.22.0-alpha.1+dev" edition = "2021" -rust-version = "1.80" +rust-version = "1.81" license = "MIT OR Apache-2.0" publish = false diff --git a/examples/rust/spawn_viewer/Cargo.toml b/examples/rust/spawn_viewer/Cargo.toml index b35b9af9876b..2b16517bf9b0 100644 --- a/examples/rust/spawn_viewer/Cargo.toml +++ b/examples/rust/spawn_viewer/Cargo.toml @@ -2,7 +2,7 @@ name = "spawn_viewer" version = "0.22.0-alpha.1+dev" edition = "2021" -rust-version = "1.80" +rust-version = "1.81" license = "MIT OR Apache-2.0" publish = false diff --git a/examples/rust/stdio/Cargo.toml b/examples/rust/stdio/Cargo.toml index 9a410b830cdb..8966b236b5a3 100644 --- a/examples/rust/stdio/Cargo.toml +++ b/examples/rust/stdio/Cargo.toml @@ -2,7 +2,7 @@ name = "stdio" version = "0.22.0-alpha.1+dev" edition = "2021" -rust-version = "1.80" +rust-version = "1.81" license = "MIT OR Apache-2.0" publish = false diff --git a/examples/rust/template/Cargo.toml b/examples/rust/template/Cargo.toml index 61932c222612..38c375a8ecf4 100644 --- a/examples/rust/template/Cargo.toml +++ b/examples/rust/template/Cargo.toml @@ -2,7 +2,7 @@ name = "template" version = "0.22.0-alpha.1+dev" edition = "2021" -rust-version = "1.80" +rust-version = "1.81" license = "MIT OR Apache-2.0" publish = false diff --git a/rust-toolchain b/rust-toolchain index 38e5e90f3acf..0eefd31bc5a3 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -5,6 +5,6 @@ # to the user in the error, instead of "error: invalid channel name '[toolchain]'". [toolchain] -channel = "1.80.0" +channel = "1.81.0" components = ["rustfmt", "clippy"] targets = ["wasm32-unknown-unknown"] diff --git a/scripts/check_env.py b/scripts/check_env.py index 66c6cdd9854d..c93375c3fc3b 100644 --- a/scripts/check_env.py +++ b/scripts/check_env.py @@ -7,8 +7,8 @@ import subprocess PIXI_VERSION = "0.39.0" -CARGO_VERSION = "1.80.0" -RUST_VERSION = "1.80.0" +CARGO_VERSION = "1.81.0" +RUST_VERSION = "1.81.0" def check_version(cmd: str, expected: str, update: str, install: str) -> bool: diff --git a/scripts/clippy_wasm/clippy.toml b/scripts/clippy_wasm/clippy.toml index 1db82f4f0cec..34291cb025f6 100644 --- a/scripts/clippy_wasm/clippy.toml +++ b/scripts/clippy_wasm/clippy.toml @@ -6,7 +6,7 @@ # ----------------------------------------------------------------------------- # Section identical to the main clippy.toml: -msrv = "1.80" +msrv = "1.81" allow-unwrap-in-tests = true diff --git a/scripts/lint.py b/scripts/lint.py index f99428e69a89..f9ba2ed823ea 100755 --- a/scripts/lint.py +++ b/scripts/lint.py @@ -619,7 +619,7 @@ def test_lint_workspace_deps() -> None: name = "clock" version = "0.6.0-alpha.0" edition = "2021" - rust-version = "1.80" + rust-version = "1.81" license = "MIT OR Apache-2.0" publish = false