From df7f46f23cd453f24b1d3f306ec8fb21829cd3c8 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Tue, 5 Mar 2024 10:05:33 +0100 Subject: [PATCH] Python serializable `ViewportBlueprint` (#5385) ### What * direct followup to #5372 * part of #4167 -- * necessary massaging to get the rest of `ViewportBlueprint` to serialize out of python * finished up related unit test * remove `ViewportLayout` * unify blueprint component write helpers a bit ### Checklist * [x] I have read and agree to [Contributor Guide](https://github.com/rerun-io/rerun/blob/main/CONTRIBUTING.md) and the [Code of Conduct](https://github.com/rerun-io/rerun/blob/main/CODE_OF_CONDUCT.md) * [x] I've included a screenshot or gif (if applicable) * [x] I have tested the web demo (if applicable): * Using newly built examples: [app.rerun.io](https://app.rerun.io/pr/5385/index.html) * Using examples from latest `main` build: [app.rerun.io](https://app.rerun.io/pr/5385/index.html?manifest_url=https://app.rerun.io/version/main/examples_manifest.json) * Using full set of examples from `nightly` build: [app.rerun.io](https://app.rerun.io/pr/5385/index.html?manifest_url=https://app.rerun.io/version/nightly/examples_manifest.json) * [x] The PR title and labels are set such as to maximize their usefulness for the next release's CHANGELOG * [x] If applicable, add a new check to the [release checklist](https://github.com/rerun-io/rerun/blob/main/tests/python/release_checklist)! - [PR Build Summary](https://build.rerun.io/pr/5385) - [Docs preview](https://rerun.io/preview/a5f40715a5006839a0bebdacb87485bb5c349d4d/docs) - [Examples preview](https://rerun.io/preview/a5f40715a5006839a0bebdacb87485bb5c349d4d/examples) - [Recent benchmark results](https://build.rerun.io/graphs/crates.html) - [Wasm size tracking](https://build.rerun.io/graphs/sizes.html) --- crates/re_data_ui/src/editors.rs | 16 +- .../re_space_view/src/data_query_blueprint.rs | 4 +- crates/re_space_view/src/space_view.rs | 10 +- .../src/space_view_class.rs | 8 +- .../re_types/definitions/rerun/blueprint.fbs | 1 - .../archetypes/viewport_blueprint.fbs | 9 +- .../blueprint/components/auto_layout.fbs | 1 + .../blueprint/components/auto_space_views.fbs | 1 + .../components/included_space_view.fbs | 2 +- .../blueprint/components/root_container.fbs | 8 +- .../components/space_view_maximized.fbs | 10 +- .../blueprint/components/viewport_layout.fbs | 22 -- crates/re_types_core/src/loggable_batch.rs | 30 +++ .../src/blueprint/validation_gen/mod.rs | 2 - crates/re_viewer/src/ui/override_ui.rs | 4 +- .../src/blueprint_helpers.rs | 109 ++++----- .../archetypes/viewport_blueprint.rs | 40 +--- .../src/blueprint/components/.gitattributes | 1 - .../components/included_space_view.rs | 14 +- .../src/blueprint/components/mod.rs | 4 - .../blueprint/components/root_container.rs | 1 + .../components/space_view_maximized.rs | 83 +++++-- .../components/space_view_maximized_ext.rs | 17 -- .../blueprint/components/viewport_layout.rs | 208 ------------------ .../components/viewport_layout_ext.rs | 33 --- crates/re_viewport/src/blueprint/data_ui.rs | 35 +-- crates/re_viewport/src/container.rs | 6 +- crates/re_viewport/src/viewport_blueprint.rs | 33 +-- .../archetypes/viewport_blueprint.cpp | 7 +- .../archetypes/viewport_blueprint.hpp | 17 +- rerun_cpp/src/rerun/blueprint/components.hpp | 1 - .../rerun/blueprint/components/.gitattributes | 2 - .../components/included_space_view.hpp | 15 +- .../components/space_view_maximized.cpp | 17 +- .../components/space_view_maximized.hpp | 10 +- .../blueprint/components/viewport_layout.cpp | 70 ------ .../blueprint/components/viewport_layout.hpp | 61 ----- .../archetypes/viewport_blueprint.py | 20 +- .../rerun/blueprint/components/.gitattributes | 1 - .../rerun/blueprint/components/__init__.py | 12 - .../rerun/blueprint/components/auto_layout.py | 13 +- .../blueprint/components/auto_layout_ext.py | 18 ++ .../blueprint/components/auto_space_views.py | 13 +- .../components/auto_space_views_ext.py | 18 ++ .../blueprint/components/viewport_layout.py | 71 ------ .../tests/unit/test_viewport_blueprint.py | 63 +++--- 46 files changed, 321 insertions(+), 820 deletions(-) delete mode 100644 crates/re_types/definitions/rerun/blueprint/components/viewport_layout.fbs delete mode 100644 crates/re_viewport/src/blueprint/components/space_view_maximized_ext.rs delete mode 100644 crates/re_viewport/src/blueprint/components/viewport_layout.rs delete mode 100644 crates/re_viewport/src/blueprint/components/viewport_layout_ext.rs delete mode 100644 rerun_cpp/src/rerun/blueprint/components/viewport_layout.cpp delete mode 100644 rerun_cpp/src/rerun/blueprint/components/viewport_layout.hpp create mode 100644 rerun_py/rerun_sdk/rerun/blueprint/components/auto_layout_ext.py create mode 100644 rerun_py/rerun_sdk/rerun/blueprint/components/auto_space_views_ext.py delete mode 100644 rerun_py/rerun_sdk/rerun/blueprint/components/viewport_layout.py diff --git a/crates/re_data_ui/src/editors.rs b/crates/re_data_ui/src/editors.rs index 0545e7edc95f..78b70a56d124 100644 --- a/crates/re_data_ui/src/editors.rs +++ b/crates/re_data_ui/src/editors.rs @@ -45,7 +45,7 @@ fn edit_color_ui( let [r, g, b, a] = edit_color.to_array(); let new_color = Color::from_unmultiplied_rgba(r, g, b, a); - ctx.save_blueprint_component(override_path, new_color); + ctx.save_blueprint_component(override_path, &new_color); } } @@ -86,7 +86,7 @@ fn edit_text_ui( if edit_text != current_text { let new_text = Text::from(edit_text); - ctx.save_blueprint_component(override_path, new_text); + ctx.save_blueprint_component(override_path, &new_text); } } @@ -126,7 +126,7 @@ fn edit_name_ui( if edit_text != current_text { let new_text = Name::from(edit_text); - ctx.save_blueprint_component(override_path, new_text); + ctx.save_blueprint_component(override_path, &new_text); } } @@ -175,7 +175,7 @@ fn edit_scatter_ui( if edit_scatter != current_scatter { let new_scatter = ScalarScattering::from(edit_scatter); - ctx.save_blueprint_component(override_path, new_scatter); + ctx.save_blueprint_component(override_path, &new_scatter); } } @@ -222,7 +222,7 @@ fn edit_radius_ui( if edit_radius != current_radius { let new_radius = Radius::from(edit_radius); - ctx.save_blueprint_component(override_path, new_radius); + ctx.save_blueprint_component(override_path, &new_radius); } } @@ -283,7 +283,7 @@ fn edit_marker_shape_ui( }); if edit_marker != current_marker { - ctx.save_blueprint_component(override_path, edit_marker); + ctx.save_blueprint_component(override_path, &edit_marker); } } @@ -352,7 +352,7 @@ fn edit_stroke_width_ui( if edit_stroke_width != current_stroke_width { let new_stroke_width = StrokeWidth::from(edit_stroke_width); - ctx.save_blueprint_component(override_path, new_stroke_width); + ctx.save_blueprint_component(override_path, &new_stroke_width); } } @@ -399,7 +399,7 @@ fn edit_marker_size_ui( if edit_marker_size != current_marker_size { let new_marker_size = MarkerSize::from(edit_marker_size); - ctx.save_blueprint_component(override_path, new_marker_size); + ctx.save_blueprint_component(override_path, &new_marker_size); } } diff --git a/crates/re_space_view/src/data_query_blueprint.rs b/crates/re_space_view/src/data_query_blueprint.rs index 3c301e434489..e0e519e54d49 100644 --- a/crates/re_space_view/src/data_query_blueprint.rs +++ b/crates/re_space_view/src/data_query_blueprint.rs @@ -124,7 +124,7 @@ impl DataQueryBlueprint { ctx.save_blueprint_component( &self.id.as_entity_path(), - QueryExpressions::from(&self.entity_path_filter), + &QueryExpressions::from(&self.entity_path_filter), ); } @@ -175,7 +175,7 @@ impl DataQueryBlueprint { pub fn clear(&self, ctx: &ViewerContext<'_>) { let clear = Clear::recursive(); - ctx.save_blueprint_component(&self.id.as_entity_path(), clear.is_recursive); + ctx.save_blueprint_component(&self.id.as_entity_path(), &clear.is_recursive); } pub fn build_resolver<'a>( diff --git a/crates/re_space_view/src/space_view.rs b/crates/re_space_view/src/space_view.rs index 1f1b31b751d3..1dd73f4f2a1e 100644 --- a/crates/re_space_view/src/space_view.rs +++ b/crates/re_space_view/src/space_view.rs @@ -317,7 +317,7 @@ impl SpaceViewBlueprint { pub fn clear(&self, ctx: &ViewerContext<'_>) { let clear = Clear::recursive(); - ctx.save_blueprint_component(&self.entity_path(), clear.is_recursive); + ctx.save_blueprint_component(&self.entity_path(), &clear.is_recursive); for query in &self.queries { query.clear(ctx); @@ -328,7 +328,7 @@ impl SpaceViewBlueprint { pub fn set_entity_determined_by_user(&self, ctx: &ViewerContext<'_>) { if !self.entities_determined_by_user { let component = EntitiesDeterminedByUser(true); - ctx.save_blueprint_component(&self.entity_path(), component); + ctx.save_blueprint_component(&self.entity_path(), &component); } } @@ -338,7 +338,7 @@ impl SpaceViewBlueprint { match name { Some(name) => { let component = Name(name.into()); - ctx.save_blueprint_component(&self.entity_path(), component); + ctx.save_blueprint_component(&self.entity_path(), &component); } None => { ctx.save_empty_blueprint_component::(&self.entity_path()); @@ -351,7 +351,7 @@ impl SpaceViewBlueprint { pub fn set_origin(&self, ctx: &ViewerContext<'_>, origin: &EntityPath) { if origin != &self.space_origin { let component = SpaceViewOrigin(origin.into()); - ctx.save_blueprint_component(&self.entity_path(), component); + ctx.save_blueprint_component(&self.entity_path(), &component); } } @@ -359,7 +359,7 @@ impl SpaceViewBlueprint { pub fn set_visible(&self, ctx: &ViewerContext<'_>, visible: bool) { if visible != self.visible { let component = Visible(visible); - ctx.save_blueprint_component(&self.entity_path(), component); + ctx.save_blueprint_component(&self.entity_path(), &component); } } diff --git a/crates/re_space_view_time_series/src/space_view_class.rs b/crates/re_space_view_time_series/src/space_view_class.rs index d4f9b93d8b33..376303e79108 100644 --- a/crates/re_space_view_time_series/src/space_view_class.rs +++ b/crates/re_space_view_time_series/src/space_view_class.rs @@ -625,7 +625,7 @@ fn legend_ui(ctx: &ViewerContext<'_>, space_view_id: SpaceViewId, ui: &mut egui: let mut edit_visibility = visible; ctx.re_ui.checkbox(ui, &mut edit_visibility.0, "Visible"); if visible != edit_visibility { - ctx.save_blueprint_component(&blueprint_path, edit_visibility); + ctx.save_blueprint_component(&blueprint_path, &edit_visibility); } let corner = corner.unwrap_or(DEFAULT_LEGEND_CORNER.into()); @@ -658,7 +658,7 @@ fn legend_ui(ctx: &ViewerContext<'_>, space_view_id: SpaceViewId, ui: &mut egui: ); }); if corner != edit_corner { - ctx.save_blueprint_component(&blueprint_path, edit_corner); + ctx.save_blueprint_component(&blueprint_path, &edit_corner); } }); @@ -726,7 +726,7 @@ fn axis_ui( }); if y_range != Some(range_edit) { - ctx.save_blueprint_component(&blueprint_path, range_edit); + ctx.save_blueprint_component(&blueprint_path, &range_edit); } } else if y_range.is_some() { ctx.save_empty_blueprint_component::(&blueprint_path); @@ -751,7 +751,7 @@ fn axis_ui( "If set, when zooming, the Y axis range will remain locked to the specified range.", ); if y_lock_zoom != edit_locked { - ctx.save_blueprint_component(&blueprint_path, edit_locked); + ctx.save_blueprint_component(&blueprint_path, &edit_locked); } }) }); diff --git a/crates/re_types/definitions/rerun/blueprint.fbs b/crates/re_types/definitions/rerun/blueprint.fbs index 1c0fbe702f35..9168e3548e6d 100644 --- a/crates/re_types/definitions/rerun/blueprint.fbs +++ b/crates/re_types/definitions/rerun/blueprint.fbs @@ -16,7 +16,6 @@ include "./blueprint/components/row_shares.fbs"; include "./blueprint/components/space_view_class.fbs"; include "./blueprint/components/space_view_maximized.fbs"; include "./blueprint/components/space_view_origin.fbs"; -include "./blueprint/components/viewport_layout.fbs"; include "./blueprint/components/visible.fbs"; include "./blueprint/components/corner_2d.fbs"; include "./blueprint/components/lock_range_during_zoom.fbs"; diff --git a/crates/re_types/definitions/rerun/blueprint/archetypes/viewport_blueprint.fbs b/crates/re_types/definitions/rerun/blueprint/archetypes/viewport_blueprint.fbs index a6fa133e8276..e36bd4a9629c 100644 --- a/crates/re_types/definitions/rerun/blueprint/archetypes/viewport_blueprint.fbs +++ b/crates/re_types/definitions/rerun/blueprint/archetypes/viewport_blueprint.fbs @@ -20,20 +20,21 @@ table ViewportBlueprint ( // --- Optional --- - /// The layout of the space-views - layout: rerun.blueprint.components.ViewportLayout ("attr.rerun.component_optional", nullable, order: 2000); - /// The layout of the space-views root_container: rerun.blueprint.components.RootContainer ("attr.rerun.component_optional", nullable, order: 2500); /// Show one tab as maximized? maximized: rerun.blueprint.components.SpaceViewMaximized ("attr.rerun.component_optional", nullable, order: 3000); + // TODO(andreas): This is to be removed in the future, all new space views without an explicit container + // should always insert themselves using a heuristic. /// Whether the viewport layout is determined automatically. /// - /// Set to `false` the first time the user messes around with the viewport blueprint. + /// If `true`, the container layout will be reset whenever a new space view is added or removed. + /// This defaults to `false` and is automatically set to `false` when there is user determined layout. auto_layout: rerun.blueprint.components.AutoLayout ("attr.rerun.component_optional", nullable, order: 4000); + // TODO(jleibs): This should come with an optional container id that specifies where to insert new space views. /// Whether or not space views should be created automatically. auto_space_views: rerun.blueprint.components.AutoSpaceViews ("attr.rerun.component_optional", nullable, order: 5000); } diff --git a/crates/re_types/definitions/rerun/blueprint/components/auto_layout.fbs b/crates/re_types/definitions/rerun/blueprint/components/auto_layout.fbs index f72b3d6a0cc5..4e4f37f588c3 100644 --- a/crates/re_types/definitions/rerun/blueprint/components/auto_layout.fbs +++ b/crates/re_types/definitions/rerun/blueprint/components/auto_layout.fbs @@ -15,6 +15,7 @@ namespace rerun.blueprint.components; struct AutoLayout ( "attr.arrow.transparent", "attr.rerun.scope": "blueprint", + "attr.python.aliases": "bool", "attr.rust.derive": "Copy", "attr.rust.override_crate": "re_viewport", "attr.rust.repr": "transparent", diff --git a/crates/re_types/definitions/rerun/blueprint/components/auto_space_views.fbs b/crates/re_types/definitions/rerun/blueprint/components/auto_space_views.fbs index 4d9366a533b6..e8b7bb4b3c7f 100644 --- a/crates/re_types/definitions/rerun/blueprint/components/auto_space_views.fbs +++ b/crates/re_types/definitions/rerun/blueprint/components/auto_space_views.fbs @@ -15,6 +15,7 @@ namespace rerun.blueprint.components; struct AutoSpaceViews ( "attr.arrow.transparent", "attr.rerun.scope": "blueprint", + "attr.python.aliases": "bool", "attr.rust.derive": "Copy, Default", "attr.rust.override_crate": "re_viewport", "attr.rust.repr": "transparent", diff --git a/crates/re_types/definitions/rerun/blueprint/components/included_space_view.fbs b/crates/re_types/definitions/rerun/blueprint/components/included_space_view.fbs index 1807c7ba44d8..9cc09dae54e7 100644 --- a/crates/re_types/definitions/rerun/blueprint/components/included_space_view.fbs +++ b/crates/re_types/definitions/rerun/blueprint/components/included_space_view.fbs @@ -20,5 +20,5 @@ table IncludedSpaceView ( "attr.rust.override_crate": "re_viewport", "attr.rust.repr": "transparent" ) { - space_view_ids: rerun.datatypes.Uuid (order: 100); + space_view_id: rerun.datatypes.Uuid (order: 100); } diff --git a/crates/re_types/definitions/rerun/blueprint/components/root_container.fbs b/crates/re_types/definitions/rerun/blueprint/components/root_container.fbs index fede727e44ca..5e4cc633f50a 100644 --- a/crates/re_types/definitions/rerun/blueprint/components/root_container.fbs +++ b/crates/re_types/definitions/rerun/blueprint/components/root_container.fbs @@ -12,9 +12,11 @@ namespace rerun.blueprint.components; /// The container that sits at the root of a viewport. table RootContainer ( - "attr.rerun.scope": "blueprint", - "attr.rust.derive": "Default", - "attr.rust.override_crate": "re_viewport" + "attr.rerun.scope": "blueprint", + "attr.python.aliases": "npt.NDArray[np.uint8], npt.ArrayLike, Sequence[int], bytes", + "attr.rust.derive": "Default", + "attr.rust.override_crate": "re_viewport", + "attr.rust.repr": "transparent" ) { /// `ContainerId` for the root. id: rerun.datatypes.Uuid (order: 100); diff --git a/crates/re_types/definitions/rerun/blueprint/components/space_view_maximized.fbs b/crates/re_types/definitions/rerun/blueprint/components/space_view_maximized.fbs index ff866bc93d13..cb7737517ed4 100644 --- a/crates/re_types/definitions/rerun/blueprint/components/space_view_maximized.fbs +++ b/crates/re_types/definitions/rerun/blueprint/components/space_view_maximized.fbs @@ -13,13 +13,11 @@ namespace rerun.blueprint.components; /// /// Unstable. Used for the ongoing blueprint experimentations. table SpaceViewMaximized ( - "attr.arrow.transparent", "attr.rerun.scope": "blueprint", - "attr.rust.derive": "Copy, Default, PartialEq, Eq", + "attr.python.aliases": "npt.NDArray[np.uint8], npt.ArrayLike, Sequence[int], bytes", + "attr.rust.derive": "Default", "attr.rust.override_crate": "re_viewport", - "attr.rust.repr": "transparent", - "attr.rust.tuple_struct" + "attr.rust.repr": "transparent" ) { - space_view_id: rerun.datatypes.Uuid (order: 100, nullable); + space_view_id: rerun.datatypes.Uuid (order: 100); } - diff --git a/crates/re_types/definitions/rerun/blueprint/components/viewport_layout.fbs b/crates/re_types/definitions/rerun/blueprint/components/viewport_layout.fbs deleted file mode 100644 index 1629df5d8538..000000000000 --- a/crates/re_types/definitions/rerun/blueprint/components/viewport_layout.fbs +++ /dev/null @@ -1,22 +0,0 @@ -include "arrow/attributes.fbs"; -include "python/attributes.fbs"; -include "rust/attributes.fbs"; - -include "rerun/datatypes.fbs"; -include "rerun/attributes.fbs"; - -namespace rerun.blueprint.components; - -// --- - -/// The layouts of all the space views. -/// -/// Unstable. Used for the ongoing blueprint experimentations. -table ViewportLayout ( - "attr.arrow.transparent", - "attr.rerun.scope": "blueprint", - "attr.rust.derive": "PartialEq", - "attr.rust.override_crate": "re_viewport" -) { - tree: [ubyte] (order: 101, "attr.rust.serde_type": "egui_tiles::Tree"); -} diff --git a/crates/re_types_core/src/loggable_batch.rs b/crates/re_types_core/src/loggable_batch.rs index 6e0ebcdc0f68..46f34f177166 100644 --- a/crates/re_types_core/src/loggable_batch.rs +++ b/crates/re_types_core/src/loggable_batch.rs @@ -147,6 +147,36 @@ impl DatatypeBatch for D {} impl ComponentBatch for C {} +// --- Unary Option --- + +impl LoggableBatch for Option { + type Name = L::Name; + + #[inline] + fn name(&self) -> Self::Name { + L::name() + } + + #[inline] + fn num_instances(&self) -> usize { + self.is_some() as usize + } + + #[inline] + fn arrow_field(&self) -> arrow2::datatypes::Field { + L::arrow_field() + } + + #[inline] + fn to_arrow(&self) -> SerializationResult> { + L::to_arrow(self.iter().map(|v| std::borrow::Cow::Borrowed(v))) + } +} + +impl DatatypeBatch for Option {} + +impl ComponentBatch for Option {} + // --- Vec --- impl LoggableBatch for Vec { diff --git a/crates/re_viewer/src/blueprint/validation_gen/mod.rs b/crates/re_viewer/src/blueprint/validation_gen/mod.rs index 4b4e5f6562b7..093903cab02e 100644 --- a/crates/re_viewer/src/blueprint/validation_gen/mod.rs +++ b/crates/re_viewer/src/blueprint/validation_gen/mod.rs @@ -22,7 +22,6 @@ pub use re_viewport::blueprint::components::GridColumns; pub use re_viewport::blueprint::components::IncludedSpaceView; pub use re_viewport::blueprint::components::RootContainer; pub use re_viewport::blueprint::components::SpaceViewMaximized; -pub use re_viewport::blueprint::components::ViewportLayout; /// Because blueprints are both read and written the schema must match what /// we expect to find or else we will run into all kinds of problems. @@ -48,6 +47,5 @@ pub fn is_valid_blueprint(blueprint: &EntityDb) -> bool { && validate_component::(blueprint) && validate_component::(blueprint) && validate_component::(blueprint) - && validate_component::(blueprint) && validate_component::(blueprint) } diff --git a/crates/re_viewer/src/ui/override_ui.rs b/crates/re_viewer/src/ui/override_ui.rs index 78936aac7ff2..e13259772585 100644 --- a/crates/re_viewer/src/ui/override_ui.rs +++ b/crates/re_viewer/src/ui/override_ui.rs @@ -379,7 +379,7 @@ pub fn override_visualizer_ui( .collect::>(), ); - ctx.save_blueprint_component(override_path, component); + ctx.save_blueprint_component(override_path, &component); } }); // Visualizer label @@ -462,7 +462,7 @@ pub fn add_new_visualizer( .collect::>(), ); - ctx.save_blueprint_component(override_path, component); + ctx.save_blueprint_component(override_path, &component); ui.close_menu(); } diff --git a/crates/re_viewer_context/src/blueprint_helpers.rs b/crates/re_viewer_context/src/blueprint_helpers.rs index 72fafcd10da9..aa997da7541d 100644 --- a/crates/re_viewer_context/src/blueprint_helpers.rs +++ b/crates/re_viewer_context/src/blueprint_helpers.rs @@ -1,8 +1,5 @@ -use re_log_types::{ - external::arrow2::datatypes::DataType, DataCell, DataRow, EntityPath, RowId, Time, TimePoint, - Timeline, -}; -use re_types::{components::InstanceKey, ComponentName}; +use re_log_types::{DataCell, DataRow, EntityPath, RowId, Time, TimePoint, Timeline}; +use re_types::{components::InstanceKey, ComponentBatch, ComponentName}; use crate::{SystemCommand, SystemCommandSender as _, ViewerContext}; @@ -18,39 +15,27 @@ pub fn blueprint_timepoint_for_writes() -> TimePoint { } impl ViewerContext<'_> { - /// Helper to save a component to the blueprint store. - pub fn save_blueprint_component<'a, C>(&self, entity_path: &EntityPath, component: C) - where - C: re_types::Component + Clone + 'a, - std::borrow::Cow<'a, C>: std::convert::From, - { - self.save_blueprint_component_data_cell(entity_path, [component].into(), 1); - } - - /// Helper to save an iterator of components to the blueprint store. - pub fn save_blueprint_component_iter<'a, C>( - &self, - entity_path: &EntityPath, - components: impl Iterator, - ) where - C: re_types::Component + Clone + 'a, - std::borrow::Cow<'a, C>: std::convert::From, - { - let components = components.collect::>(); - let num_instances = components.len() as u32; - self.save_blueprint_component_data_cell(entity_path, components.into(), num_instances); - } - - fn save_blueprint_component_data_cell( + /// Helper to save a component batch to the blueprint store. + pub fn save_blueprint_component( &self, entity_path: &EntityPath, - mut data_cell: DataCell, - num_instances: u32, + components: &dyn ComponentBatch, ) { - let timepoint = blueprint_timepoint_for_writes(); - + let mut data_cell = match DataCell::from_component_batch(components) { + Ok(data_cell) => data_cell, + Err(err) => { + re_log::error_once!( + "Failed to create DataCell for blueprint components: {}", + err + ); + return; + } + }; data_cell.compute_size_bytes(); + let num_instances = components.num_instances() as u32; + let timepoint = blueprint_timepoint_for_writes(); + let data_row_result = if num_instances == 1 { let mut splat_cell: DataCell = [InstanceKey::SPLAT].into(); splat_cell.compute_size_bytes(); @@ -80,21 +65,37 @@ impl ViewerContext<'_> { vec![row], )), Err(err) => { - // TODO(emilk): statically check that the component is a mono-component - then this cannot fail! - re_log::error_once!("Failed to create DataRow for blueprint component: {}", err); + re_log::error_once!("Failed to create DataRow for blueprint components: {}", err); } } } - /// Helper for `save_empty_blueprint_component` and `save_empty_blueprint_component_name`. - fn save_empty_blueprint_component_impl( + /// Helper to save a component to the blueprint store. + pub fn save_empty_blueprint_component<'a, C>(&self, entity_path: &EntityPath) + where + C: re_types::Component + 'a, + { + let empty: [C; 0] = []; + self.save_blueprint_component(entity_path, &empty); + } + + /// Helper to save a component to the blueprint store. + pub fn save_empty_blueprint_component_name( &self, + store: &re_data_store::DataStore, entity_path: &EntityPath, component_name: ComponentName, - datatype: DataType, ) { + let Some(datatype) = store.lookup_datatype(&component_name) else { + re_log::error_once!( + "Tried to clear a component with unknown type: {}", + component_name + ); + return; + }; + let timepoint = blueprint_timepoint_for_writes(); - let cell = DataCell::from_arrow_empty(component_name, datatype); + let cell = DataCell::from_arrow_empty(component_name, datatype.clone()); match DataRow::from_cells1( RowId::new(), @@ -110,38 +111,8 @@ impl ViewerContext<'_> { vec![row], )), Err(err) => { - // TODO(emilk): statically check that the component is a mono-component - then this cannot fail! re_log::error_once!("Failed to create DataRow for blueprint component: {}", err); } } } - - /// Helper to save a component to the blueprint store. - pub fn save_empty_blueprint_component<'a, C>(&self, entity_path: &EntityPath) - where - C: re_types::Component + 'a, - { - self.save_empty_blueprint_component_impl( - entity_path, - C::name(), - C::arrow_datatype().clone(), - ); - } - - /// Helper to save a component to the blueprint store. - pub fn save_empty_blueprint_component_name( - &self, - store: &re_data_store::DataStore, - entity_path: &EntityPath, - component_name: ComponentName, - ) { - if let Some(datatype) = store.lookup_datatype(&component_name) { - self.save_empty_blueprint_component_impl(entity_path, component_name, datatype.clone()); - } else { - re_log::error_once!( - "Tried to clear a component with unknown type: {}", - component_name - ); - } - } } diff --git a/crates/re_viewport/src/blueprint/archetypes/viewport_blueprint.rs b/crates/re_viewport/src/blueprint/archetypes/viewport_blueprint.rs index 33e2e7ee7727..20288f5f519d 100644 --- a/crates/re_viewport/src/blueprint/archetypes/viewport_blueprint.rs +++ b/crates/re_viewport/src/blueprint/archetypes/viewport_blueprint.rs @@ -27,9 +27,6 @@ pub struct ViewportBlueprint { /// All of the space-views that belong to the viewport. pub space_views: Vec, - /// The layout of the space-views - pub layout: Option, - /// The layout of the space-views pub root_container: Option, @@ -38,7 +35,8 @@ pub struct ViewportBlueprint { /// Whether the viewport layout is determined automatically. /// - /// Set to `false` the first time the user messes around with the viewport blueprint. + /// If `true`, the container layout will be reset whenever a new space view is added or removed. + /// This defaults to `false` and is automatically set to `false` when there is user determined layout. pub auto_layout: Option, /// Whether or not space views should be created automatically. @@ -49,7 +47,6 @@ impl ::re_types_core::SizeBytes for ViewportBlueprint { #[inline] fn heap_size_bytes(&self) -> u64 { self.space_views.heap_size_bytes() - + self.layout.heap_size_bytes() + self.root_container.heap_size_bytes() + self.maximized.heap_size_bytes() + self.auto_layout.heap_size_bytes() @@ -59,7 +56,6 @@ impl ::re_types_core::SizeBytes for ViewportBlueprint { #[inline] fn is_pod() -> bool { >::is_pod() - && >::is_pod() && >::is_pod() && >::is_pod() && >::is_pod() @@ -73,19 +69,18 @@ static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentName; 1usize]> = static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentName; 1usize]> = once_cell::sync::Lazy::new(|| ["rerun.blueprint.components.ViewportBlueprintIndicator".into()]); -static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentName; 6usize]> = +static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentName; 5usize]> = once_cell::sync::Lazy::new(|| { [ "rerun.blueprint.components.AutoLayout".into(), "rerun.blueprint.components.AutoSpaceViews".into(), "rerun.blueprint.components.RootContainer".into(), "rerun.blueprint.components.SpaceViewMaximized".into(), - "rerun.blueprint.components.ViewportLayout".into(), "rerun.components.InstanceKey".into(), ] }); -static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentName; 8usize]> = +static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentName; 7usize]> = once_cell::sync::Lazy::new(|| { [ "rerun.blueprint.components.IncludedSpaceView".into(), @@ -94,13 +89,12 @@ static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentName; 8usize]> = "rerun.blueprint.components.AutoSpaceViews".into(), "rerun.blueprint.components.RootContainer".into(), "rerun.blueprint.components.SpaceViewMaximized".into(), - "rerun.blueprint.components.ViewportLayout".into(), "rerun.components.InstanceKey".into(), ] }); impl ViewportBlueprint { - pub const NUM_COMPONENTS: usize = 8usize; + pub const NUM_COMPONENTS: usize = 7usize; } /// Indicator component for the [`ViewportBlueprint`] [`::re_types_core::Archetype`] @@ -162,16 +156,6 @@ impl ::re_types_core::Archetype for ViewportBlueprint { .collect::>>() .with_context("rerun.blueprint.archetypes.ViewportBlueprint#space_views")? }; - let layout = - if let Some(array) = arrays_by_name.get("rerun.blueprint.components.ViewportLayout") { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.ViewportBlueprint#layout")? - .into_iter() - .next() - .flatten() - } else { - None - }; let root_container = if let Some(array) = arrays_by_name.get("rerun.blueprint.components.RootContainer") { ::from_arrow_opt(&**array) @@ -215,7 +199,6 @@ impl ::re_types_core::Archetype for ViewportBlueprint { }; Ok(Self { space_views, - layout, root_container, maximized, auto_layout, @@ -231,9 +214,6 @@ impl ::re_types_core::AsComponents for ViewportBlueprint { [ Some(Self::indicator()), Some((&self.space_views as &dyn ComponentBatch).into()), - self.layout - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch).into()), self.root_container .as_ref() .map(|comp| (comp as &dyn ComponentBatch).into()), @@ -266,7 +246,6 @@ impl ViewportBlueprint { ) -> Self { Self { space_views: space_views.into_iter().map(Into::into).collect(), - layout: None, root_container: None, maximized: None, auto_layout: None, @@ -274,15 +253,6 @@ impl ViewportBlueprint { } } - #[inline] - pub fn with_layout( - mut self, - layout: impl Into, - ) -> Self { - self.layout = Some(layout.into()); - self - } - #[inline] pub fn with_root_container( mut self, diff --git a/crates/re_viewport/src/blueprint/components/.gitattributes b/crates/re_viewport/src/blueprint/components/.gitattributes index 94acd9b40f79..c11f4c8de1c1 100644 --- a/crates/re_viewport/src/blueprint/components/.gitattributes +++ b/crates/re_viewport/src/blueprint/components/.gitattributes @@ -9,4 +9,3 @@ included_space_view.rs linguist-generated=true mod.rs linguist-generated=true root_container.rs linguist-generated=true space_view_maximized.rs linguist-generated=true -viewport_layout.rs linguist-generated=true diff --git a/crates/re_viewport/src/blueprint/components/included_space_view.rs b/crates/re_viewport/src/blueprint/components/included_space_view.rs index 13044575f9b2..b496455b791f 100644 --- a/crates/re_viewport/src/blueprint/components/included_space_view.rs +++ b/crates/re_viewport/src/blueprint/components/included_space_view.rs @@ -167,7 +167,7 @@ impl ::re_types_core::Loggable for IncludedSpaceView { let actual = arrow_data.data_type().clone(); DeserializationError::datatype_mismatch(expected, actual) }) - .with_context("rerun.blueprint.components.IncludedSpaceView#space_view_ids")?; + .with_context("rerun.blueprint.components.IncludedSpaceView#space_view_id")?; if arrow_data.is_empty() { Vec::new() } else { @@ -184,9 +184,7 @@ impl ::re_types_core::Loggable for IncludedSpaceView { let actual = arrow_data_inner.data_type().clone(); DeserializationError::datatype_mismatch(expected, actual) }) - .with_context( - "rerun.blueprint.components.IncludedSpaceView#space_view_ids", - )? + .with_context("rerun.blueprint.components.IncludedSpaceView#space_view_id")? .into_iter() .map(|opt| opt.copied()) .collect::>() @@ -225,7 +223,7 @@ impl ::re_types_core::Loggable for IncludedSpaceView { .map(|v| v.ok_or_else(DeserializationError::missing_data)) .map(|res| res.map(|v| Some(Self(v)))) .collect::>>>() - .with_context("rerun.blueprint.components.IncludedSpaceView#space_view_ids") + .with_context("rerun.blueprint.components.IncludedSpaceView#space_view_id") .with_context("rerun.blueprint.components.IncludedSpaceView")?) } @@ -255,7 +253,7 @@ impl ::re_types_core::Loggable for IncludedSpaceView { let actual = arrow_data.data_type().clone(); DeserializationError::datatype_mismatch(expected, actual) }) - .with_context("rerun.blueprint.components.IncludedSpaceView#space_view_ids")?; + .with_context("rerun.blueprint.components.IncludedSpaceView#space_view_id")?; let arrow_data_inner = &**arrow_data.values(); bytemuck::cast_slice::<_, [_; 16usize]>( arrow_data_inner @@ -266,9 +264,7 @@ impl ::re_types_core::Loggable for IncludedSpaceView { let actual = arrow_data_inner.data_type().clone(); DeserializationError::datatype_mismatch(expected, actual) }) - .with_context( - "rerun.blueprint.components.IncludedSpaceView#space_view_ids", - )? + .with_context("rerun.blueprint.components.IncludedSpaceView#space_view_id")? .values() .as_slice(), ) diff --git a/crates/re_viewport/src/blueprint/components/mod.rs b/crates/re_viewport/src/blueprint/components/mod.rs index 7c0846e84dd5..3ca8a746c42b 100644 --- a/crates/re_viewport/src/blueprint/components/mod.rs +++ b/crates/re_viewport/src/blueprint/components/mod.rs @@ -9,9 +9,6 @@ mod grid_columns; mod included_space_view; mod root_container; mod space_view_maximized; -mod space_view_maximized_ext; -mod viewport_layout; -mod viewport_layout_ext; pub use self::auto_layout::AutoLayout; pub use self::auto_space_views::AutoSpaceViews; @@ -20,4 +17,3 @@ pub use self::grid_columns::GridColumns; pub use self::included_space_view::IncludedSpaceView; pub use self::root_container::RootContainer; pub use self::space_view_maximized::SpaceViewMaximized; -pub use self::viewport_layout::ViewportLayout; diff --git a/crates/re_viewport/src/blueprint/components/root_container.rs b/crates/re_viewport/src/blueprint/components/root_container.rs index 5f0edc646835..2558a7a00e08 100644 --- a/crates/re_viewport/src/blueprint/components/root_container.rs +++ b/crates/re_viewport/src/blueprint/components/root_container.rs @@ -23,6 +23,7 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; /// **Component**: The container that sits at the root of a viewport. #[derive(Clone, Debug, Default)] +#[repr(transparent)] pub struct RootContainer( /// `ContainerId` for the root. pub crate::datatypes::Uuid, diff --git a/crates/re_viewport/src/blueprint/components/space_view_maximized.rs b/crates/re_viewport/src/blueprint/components/space_view_maximized.rs index 1272674a2319..21258e36d64c 100644 --- a/crates/re_viewport/src/blueprint/components/space_view_maximized.rs +++ b/crates/re_viewport/src/blueprint/components/space_view_maximized.rs @@ -24,9 +24,9 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; /// **Component**: Whether a space view is maximized. /// /// Unstable. Used for the ongoing blueprint experimentations. -#[derive(Clone, Debug, Copy, Default, PartialEq, Eq)] +#[derive(Clone, Debug, Default)] #[repr(transparent)] -pub struct SpaceViewMaximized(pub Option); +pub struct SpaceViewMaximized(pub crate::datatypes::Uuid); impl ::re_types_core::SizeBytes for SpaceViewMaximized { #[inline] @@ -36,28 +36,28 @@ impl ::re_types_core::SizeBytes for SpaceViewMaximized { #[inline] fn is_pod() -> bool { - >::is_pod() + ::is_pod() } } -impl>> From for SpaceViewMaximized { +impl> From for SpaceViewMaximized { fn from(v: T) -> Self { Self(v.into()) } } -impl std::borrow::Borrow> for SpaceViewMaximized { +impl std::borrow::Borrow for SpaceViewMaximized { #[inline] - fn borrow(&self) -> &Option { + fn borrow(&self) -> &crate::datatypes::Uuid { &self.0 } } impl std::ops::Deref for SpaceViewMaximized { - type Target = Option; + type Target = crate::datatypes::Uuid; #[inline] - fn deref(&self) -> &Option { + fn deref(&self) -> &crate::datatypes::Uuid { &self.0 } } @@ -96,12 +96,10 @@ impl ::re_types_core::Loggable for SpaceViewMaximized { .into_iter() .map(|datum| { let datum: Option<::std::borrow::Cow<'a, Self>> = datum.map(Into::into); - let datum = datum - .map(|datum| { - let Self(data0) = datum.into_owned(); - data0 - }) - .flatten(); + let datum = datum.map(|datum| { + let Self(data0) = datum.into_owned(); + data0 + }); (datum.is_some(), datum) }) .unzip(); @@ -224,10 +222,65 @@ impl ::re_types_core::Loggable for SpaceViewMaximized { } .into_iter() } - .map(Ok) + .map(|v| v.ok_or_else(DeserializationError::missing_data)) .map(|res| res.map(|v| Some(Self(v)))) .collect::>>>() .with_context("rerun.blueprint.components.SpaceViewMaximized#space_view_id") .with_context("rerun.blueprint.components.SpaceViewMaximized")?) } + + #[allow(clippy::wildcard_imports)] + #[inline] + fn from_arrow(arrow_data: &dyn arrow2::array::Array) -> DeserializationResult> + where + Self: Sized, + { + use ::re_types_core::{Loggable as _, ResultExt as _}; + use arrow2::{array::*, buffer::*, datatypes::*}; + if let Some(validity) = arrow_data.validity() { + if validity.unset_bits() != 0 { + return Err(DeserializationError::missing_data()); + } + } + Ok({ + let slice = { + let arrow_data = arrow_data + .as_any() + .downcast_ref::() + .ok_or_else(|| { + let expected = DataType::FixedSizeList( + std::sync::Arc::new(Field::new("item", DataType::UInt8, false)), + 16usize, + ); + let actual = arrow_data.data_type().clone(); + DeserializationError::datatype_mismatch(expected, actual) + }) + .with_context("rerun.blueprint.components.SpaceViewMaximized#space_view_id")?; + let arrow_data_inner = &**arrow_data.values(); + bytemuck::cast_slice::<_, [_; 16usize]>( + arrow_data_inner + .as_any() + .downcast_ref::() + .ok_or_else(|| { + let expected = DataType::UInt8; + let actual = arrow_data_inner.data_type().clone(); + DeserializationError::datatype_mismatch(expected, actual) + }) + .with_context( + "rerun.blueprint.components.SpaceViewMaximized#space_view_id", + )? + .values() + .as_slice(), + ) + }; + { + slice + .iter() + .copied() + .map(|bytes| crate::datatypes::Uuid { bytes }) + .map(|v| Self(v)) + .collect::>() + } + }) + } } diff --git a/crates/re_viewport/src/blueprint/components/space_view_maximized_ext.rs b/crates/re_viewport/src/blueprint/components/space_view_maximized_ext.rs deleted file mode 100644 index 2bd22e0635c3..000000000000 --- a/crates/re_viewport/src/blueprint/components/space_view_maximized_ext.rs +++ /dev/null @@ -1,17 +0,0 @@ -#[test] -fn test_space_view_maximized() { - use super::SpaceViewMaximized; - - use re_types::Loggable as _; - use re_viewer_context::SpaceViewId; - - for data in [ - [SpaceViewMaximized(None)], - [SpaceViewMaximized(Some(SpaceViewId::random().into()))], - ] { - let array: Box = - SpaceViewMaximized::to_arrow(data.as_slice()).unwrap(); - let ret: Vec = SpaceViewMaximized::from_arrow(array.as_ref()).unwrap(); - assert_eq!(&data, ret.as_slice()); - } -} diff --git a/crates/re_viewport/src/blueprint/components/viewport_layout.rs b/crates/re_viewport/src/blueprint/components/viewport_layout.rs deleted file mode 100644 index b36b5ee4d781..000000000000 --- a/crates/re_viewport/src/blueprint/components/viewport_layout.rs +++ /dev/null @@ -1,208 +0,0 @@ -// DO NOT EDIT! This file was auto-generated by crates/re_types_builder/src/codegen/rust/api.rs -// Based on "crates/re_types/definitions/rerun/blueprint/components/viewport_layout.fbs". - -#![allow(trivial_numeric_casts)] -#![allow(unused_imports)] -#![allow(unused_parens)] -#![allow(clippy::clone_on_copy)] -#![allow(clippy::iter_on_single_items)] -#![allow(clippy::map_flatten)] -#![allow(clippy::match_wildcard_for_single_variants)] -#![allow(clippy::needless_question_mark)] -#![allow(clippy::new_without_default)] -#![allow(clippy::redundant_closure)] -#![allow(clippy::too_many_arguments)] -#![allow(clippy::too_many_lines)] -#![allow(clippy::unnecessary_cast)] - -use ::re_types_core::external::arrow2; -use ::re_types_core::ComponentName; -use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, MaybeOwnedComponentBatch}; -use ::re_types_core::{DeserializationError, DeserializationResult}; - -/// **Component**: The layouts of all the space views. -/// -/// Unstable. Used for the ongoing blueprint experimentations. -#[derive(Clone, Debug, PartialEq)] -pub struct ViewportLayout(pub egui_tiles::Tree); - -impl From> for ViewportLayout { - #[inline] - fn from(tree: egui_tiles::Tree) -> Self { - Self(tree) - } -} - -impl From for egui_tiles::Tree { - #[inline] - fn from(value: ViewportLayout) -> Self { - value.0 - } -} - -::re_types_core::macros::impl_into_cow!(ViewportLayout); - -impl ::re_types_core::Loggable for ViewportLayout { - type Name = ::re_types_core::ComponentName; - - #[inline] - fn name() -> Self::Name { - "rerun.blueprint.components.ViewportLayout".into() - } - - #[allow(clippy::wildcard_imports)] - #[inline] - fn arrow_datatype() -> arrow2::datatypes::DataType { - use arrow2::datatypes::*; - DataType::List(std::sync::Arc::new(Field::new( - "item", - DataType::UInt8, - false, - ))) - } - - #[allow(clippy::wildcard_imports)] - fn to_arrow_opt<'a>( - data: impl IntoIterator>>>, - ) -> SerializationResult> - where - Self: Clone + 'a, - { - use ::re_types_core::{Loggable as _, ResultExt as _}; - use arrow2::{array::*, datatypes::*}; - Ok({ - let (somes, data0): (Vec<_>, Vec<_>) = data - .into_iter() - .map(|datum| { - let datum: Option<::std::borrow::Cow<'a, Self>> = datum.map(Into::into); - let datum = datum.map(|datum| { - let Self(data0) = datum.into_owned(); - data0 - }); - (datum.is_some(), datum) - }) - .unzip(); - let data0_bitmap: Option = { - let any_nones = somes.iter().any(|some| !*some); - any_nones.then(|| somes.into()) - }; - { - use arrow2::{buffer::Buffer, offset::OffsetsBuffer}; - let buffers: Vec>> = data0 - .iter() - .map(|opt| { - use ::re_types_core::SerializationError; - opt.as_ref() - .map(|b| { - let mut buf = Vec::new(); - rmp_serde::encode::write_named(&mut buf, b).map_err(|err| { - SerializationError::serde_failure(err.to_string()) - })?; - Ok(buf) - }) - .transpose() - }) - .collect::>>()?; - let offsets = arrow2::offset::Offsets::::try_from_lengths( - buffers - .iter() - .map(|opt| opt.as_ref().map(|buf| buf.len()).unwrap_or_default()), - ) - .unwrap() - .into(); - let data0_inner_bitmap: Option = None; - let data0_inner_data: Buffer = buffers - .into_iter() - .flatten() - .collect::>() - .concat() - .into(); - ListArray::new( - Self::arrow_datatype(), - offsets, - PrimitiveArray::new(DataType::UInt8, data0_inner_data, data0_inner_bitmap) - .boxed(), - data0_bitmap, - ) - .boxed() - } - }) - } - - #[allow(clippy::wildcard_imports)] - fn from_arrow_opt( - arrow_data: &dyn arrow2::array::Array, - ) -> DeserializationResult>> - where - Self: Sized, - { - use ::re_types_core::{Loggable as _, ResultExt as _}; - use arrow2::{array::*, buffer::*, datatypes::*}; - 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.blueprint.components.ViewportLayout#tree")?; - if arrow_data.is_empty() { - Vec::new() - } else { - let arrow_data_inner = { - let arrow_data_inner = &**arrow_data.values(); - arrow_data_inner - .as_any() - .downcast_ref::() - .ok_or_else(|| { - let expected = DataType::UInt8; - let actual = arrow_data_inner.data_type().clone(); - DeserializationError::datatype_mismatch(expected, actual) - }) - .with_context("rerun.blueprint.components.ViewportLayout#tree")? - .values() - }; - let offsets = arrow_data.offsets(); - arrow2::bitmap::utils::ZipValidity::new_with_validity( - offsets.iter().zip(offsets.lengths()), - arrow_data.validity(), - ) - .map(|elem| { - elem.map(|(start, len)| { - let start = *start as usize; - let end = start + len; - if end as usize > arrow_data_inner.len() { - 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 as usize, end - start as usize) - }; - let data = rmp_serde::from_slice::< - egui_tiles::Tree, - >(data.as_slice()) - .map_err(|err| DeserializationError::serde_failure(err.to_string()))?; - Ok(data) - }) - .transpose() - }) - .collect::>>>()? - } - .into_iter() - } - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .map(|res| res.map(|v| Some(Self(v)))) - .collect::>>>() - .with_context("rerun.blueprint.components.ViewportLayout#tree") - .with_context("rerun.blueprint.components.ViewportLayout")?) - } -} diff --git a/crates/re_viewport/src/blueprint/components/viewport_layout_ext.rs b/crates/re_viewport/src/blueprint/components/viewport_layout_ext.rs deleted file mode 100644 index e5ac57985088..000000000000 --- a/crates/re_viewport/src/blueprint/components/viewport_layout_ext.rs +++ /dev/null @@ -1,33 +0,0 @@ -use super::ViewportLayout; - -impl Default for ViewportLayout { - fn default() -> Self { - Self(egui_tiles::Tree::empty("viewport_tree")) - } -} - -impl re_types_core::SizeBytes for ViewportLayout { - #[inline] - fn heap_size_bytes(&self) -> u64 { - // TODO(cmc): Implementing SizeBytes for this type would require a lot of effort, - // which would be wasted since this is supposed to go away very soon. - #[allow(clippy::manual_assert)] // readability - if cfg!(debug_assertions) { - panic!("ViewportLayout does not report its size properly"); - } - - 0 - } -} - -#[test] -fn test_viewport_layout() { - use re_types::Loggable as _; - - let viewport_layout = ViewportLayout::default(); - - let data = [viewport_layout]; - let array: Box = ViewportLayout::to_arrow(data.as_slice()).unwrap(); - let ret: Vec = ViewportLayout::from_arrow(array.as_ref()).unwrap(); - assert_eq!(data.to_vec(), ret); -} diff --git a/crates/re_viewport/src/blueprint/data_ui.rs b/crates/re_viewport/src/blueprint/data_ui.rs index 920150635e5f..ae5010180662 100644 --- a/crates/re_viewport/src/blueprint/data_ui.rs +++ b/crates/re_viewport/src/blueprint/data_ui.rs @@ -1,7 +1,7 @@ use re_data_ui::{add_to_registry, DataUi}; use re_viewer_context::{ComponentUiRegistry, SpaceViewId, UiVerbosity, ViewerContext}; -use super::components::{IncludedSpaceView, SpaceViewMaximized, ViewportLayout}; +use super::components::{IncludedSpaceView, SpaceViewMaximized}; impl DataUi for IncludedSpaceView { #[allow(clippy::only_used_in_recursion)] @@ -28,36 +28,8 @@ impl DataUi for SpaceViewMaximized { query: &re_data_store::LatestAtQuery, store: &re_data_store::DataStore, ) { - match self.0 { - Some(space_view) => { - let space_view: SpaceViewId = space_view.into(); - space_view.data_ui(ctx, ui, verbosity, query, store); - } - None => { - ui.label("None"); - } - } - } -} - -impl DataUi for ViewportLayout { - #[allow(clippy::only_used_in_recursion)] - fn data_ui( - &self, - _ctx: &ViewerContext<'_>, - ui: &mut egui::Ui, - verbosity: UiVerbosity, - _query: &re_data_store::LatestAtQuery, - _store: &re_data_store::DataStore, - ) { - match verbosity { - UiVerbosity::Small => { - ui.label(format!("ViewportLayout with {} tiles", self.0.tiles.len())); - } - UiVerbosity::Full | UiVerbosity::LimitHeight | UiVerbosity::Reduced => { - ui.label(format!("{:?}", self.0)); - } - } + let space_view: SpaceViewId = self.0.into(); + space_view.data_ui(ctx, ui, verbosity, query, store); } } @@ -66,5 +38,4 @@ pub fn register_ui_components(registry: &mut ComponentUiRegistry) { add_to_registry::(registry); add_to_registry::(registry); - add_to_registry::(registry); } diff --git a/crates/re_viewport/src/container.rs b/crates/re_viewport/src/container.rs index 6675337c7788..068b7195e5d1 100644 --- a/crates/re_viewport/src/container.rs +++ b/crates/re_viewport/src/container.rs @@ -340,7 +340,7 @@ impl ContainerBlueprint { pub fn set_visible(&self, ctx: &ViewerContext<'_>, visible: bool) { if visible != self.visible { let component = Visible(visible); - ctx.save_blueprint_component(&self.entity_path(), component); + ctx.save_blueprint_component(&self.entity_path(), &component); } } @@ -349,7 +349,7 @@ impl ContainerBlueprint { if grid_columns != self.grid_columns { if let Some(grid_columns) = grid_columns { let component = GridColumns(grid_columns); - ctx.save_blueprint_component(&self.entity_path(), component); + ctx.save_blueprint_component(&self.entity_path(), &component); } else { ctx.save_empty_blueprint_component::(&self.entity_path()); } @@ -360,7 +360,7 @@ impl ContainerBlueprint { // TODO(jleibs): Should this be a recursive clear? pub fn clear(&self, ctx: &ViewerContext<'_>) { let clear = Clear::recursive(); - ctx.save_blueprint_component(&self.entity_path(), clear.is_recursive); + ctx.save_blueprint_component(&self.entity_path(), &clear.is_recursive); } pub fn to_tile(&self) -> egui_tiles::Tile { diff --git a/crates/re_viewport/src/viewport_blueprint.rs b/crates/re_viewport/src/viewport_blueprint.rs index 745fb75d6057..48186c14c6ea 100644 --- a/crates/re_viewport/src/viewport_blueprint.rs +++ b/crates/re_viewport/src/viewport_blueprint.rs @@ -13,7 +13,6 @@ use re_viewer_context::{ContainerId, Item, SpaceViewClassIdentifier, SpaceViewId use crate::{ blueprint::components::{ AutoLayout, AutoSpaceViews, IncludedSpaceView, RootContainer, SpaceViewMaximized, - ViewportLayout, }, container::{blueprint_id_to_tile_id, ContainerBlueprint, Contents}, viewport::TreeAction, @@ -130,7 +129,7 @@ impl ViewportBlueprint { |auto| auto.0, ); - let maximized = arch.maximized.and_then(|id| id.0.map(|id| id.into())); + let maximized = arch.maximized.map(|id| id.0.into()); let tree = build_tree_from_space_views_and_containers( space_views.values(), @@ -225,8 +224,9 @@ impl ViewportBlueprint { .space_views .keys() .filter(|id| id != &space_view_id) - .map(|id| IncludedSpaceView((*id).into())); - ctx.save_blueprint_component_iter(&VIEWPORT_PATH.into(), components); + .map(|id| IncludedSpaceView((*id).into())) + .collect::>(); + ctx.save_blueprint_component(&VIEWPORT_PATH.into(), &components); } /// Duplicates a space view and its entity property overrides. @@ -329,9 +329,9 @@ impl ViewportBlueprint { .space_views .keys() .chain(new_ids.iter()) - .map(|id| IncludedSpaceView((*id).into())); - - ctx.save_blueprint_component_iter(&VIEWPORT_PATH.into(), components); + .map(|id| IncludedSpaceView((*id).into())) + .collect::>(); + ctx.save_blueprint_component(&VIEWPORT_PATH.into(), &components); } new_ids @@ -654,7 +654,7 @@ impl ViewportBlueprint { if old_value != value { let component = AutoLayout(value); - ctx.save_blueprint_component(&VIEWPORT_PATH.into(), component); + ctx.save_blueprint_component(&VIEWPORT_PATH.into(), &component); } } @@ -669,7 +669,7 @@ impl ViewportBlueprint { if old_value != value { let component = AutoSpaceViews(value); - ctx.save_blueprint_component(&VIEWPORT_PATH.into(), component); + ctx.save_blueprint_component(&VIEWPORT_PATH.into(), &component); } } @@ -681,17 +681,8 @@ impl ViewportBlueprint { #[inline] pub fn set_maximized(&self, space_view_id: Option, ctx: &ViewerContext<'_>) { if self.maximized != space_view_id { - let component = SpaceViewMaximized(space_view_id.map(|id| id.into())); - ctx.save_blueprint_component(&VIEWPORT_PATH.into(), component); - } - } - - #[inline] - pub fn set_tree(&self, tree: &egui_tiles::Tree, ctx: &ViewerContext<'_>) { - if &self.tree != tree { - re_log::trace!("Updating the layout tree"); - let component = ViewportLayout(tree.clone()); - ctx.save_blueprint_component(&VIEWPORT_PATH.into(), component); + let component_batch = space_view_id.map(|id| SpaceViewMaximized(id.into())); + ctx.save_blueprint_component(&VIEWPORT_PATH.into(), &component_batch); } } @@ -791,7 +782,7 @@ impl ViewportBlueprint { .and_then(|contents| contents.as_container_id()) .map(|container_id| RootContainer((container_id).into())) { - ctx.save_blueprint_component(&VIEWPORT_PATH.into(), root_container); + ctx.save_blueprint_component(&VIEWPORT_PATH.into(), &root_container); } else { ctx.save_empty_blueprint_component::(&VIEWPORT_PATH.into()); } diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/viewport_blueprint.cpp b/rerun_cpp/src/rerun/blueprint/archetypes/viewport_blueprint.cpp index 1d5971800c1a..85f2d414882e 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/viewport_blueprint.cpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/viewport_blueprint.cpp @@ -14,18 +14,13 @@ namespace rerun { ) { using namespace blueprint::archetypes; std::vector cells; - cells.reserve(7); + cells.reserve(6); { auto result = DataCell::from_loggable(archetype.space_views); RR_RETURN_NOT_OK(result.error); cells.push_back(std::move(result.value)); } - if (archetype.layout.has_value()) { - auto result = DataCell::from_loggable(archetype.layout.value()); - RR_RETURN_NOT_OK(result.error); - cells.push_back(std::move(result.value)); - } if (archetype.root_container.has_value()) { auto result = DataCell::from_loggable(archetype.root_container.value()); RR_RETURN_NOT_OK(result.error); diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/viewport_blueprint.hpp b/rerun_cpp/src/rerun/blueprint/archetypes/viewport_blueprint.hpp index 814983a13eea..49ccd536be15 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/viewport_blueprint.hpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/viewport_blueprint.hpp @@ -8,7 +8,6 @@ #include "../../blueprint/components/included_space_view.hpp" #include "../../blueprint/components/root_container.hpp" #include "../../blueprint/components/space_view_maximized.hpp" -#include "../../blueprint/components/viewport_layout.hpp" #include "../../collection.hpp" #include "../../compiler_utils.hpp" #include "../../data_cell.hpp" @@ -26,9 +25,6 @@ namespace rerun::blueprint::archetypes { /// All of the space-views that belong to the viewport. Collection space_views; - /// The layout of the space-views - std::optional layout; - /// The layout of the space-views std::optional root_container; @@ -37,7 +33,8 @@ namespace rerun::blueprint::archetypes { /// Whether the viewport layout is determined automatically. /// - /// Set to `false` the first time the user messes around with the viewport blueprint. + /// If `true`, the container layout will be reset whenever a new space view is added or removed. + /// This defaults to `false` and is automatically set to `false` when there is user determined layout. std::optional auto_layout; /// Whether or not space views should be created automatically. @@ -59,13 +56,6 @@ namespace rerun::blueprint::archetypes { ) : space_views(std::move(_space_views)) {} - /// The layout of the space-views - ViewportBlueprint with_layout(rerun::blueprint::components::ViewportLayout _layout) && { - layout = std::move(_layout); - // See: https://github.com/rerun-io/rerun/issues/4027 - RR_WITH_MAYBE_UNINITIALIZED_DISABLED(return std::move(*this);) - } - /// The layout of the space-views ViewportBlueprint with_root_container( rerun::blueprint::components::RootContainer _root_container @@ -85,7 +75,8 @@ namespace rerun::blueprint::archetypes { /// Whether the viewport layout is determined automatically. /// - /// Set to `false` the first time the user messes around with the viewport blueprint. + /// If `true`, the container layout will be reset whenever a new space view is added or removed. + /// This defaults to `false` and is automatically set to `false` when there is user determined layout. ViewportBlueprint with_auto_layout(rerun::blueprint::components::AutoLayout _auto_layout ) && { auto_layout = std::move(_auto_layout); diff --git a/rerun_cpp/src/rerun/blueprint/components.hpp b/rerun_cpp/src/rerun/blueprint/components.hpp index cc5c39fc512d..eb115a04310e 100644 --- a/rerun_cpp/src/rerun/blueprint/components.hpp +++ b/rerun_cpp/src/rerun/blueprint/components.hpp @@ -22,5 +22,4 @@ #include "blueprint/components/space_view_class.hpp" #include "blueprint/components/space_view_maximized.hpp" #include "blueprint/components/space_view_origin.hpp" -#include "blueprint/components/viewport_layout.hpp" #include "blueprint/components/visible.hpp" diff --git a/rerun_cpp/src/rerun/blueprint/components/.gitattributes b/rerun_cpp/src/rerun/blueprint/components/.gitattributes index ccee84c265a2..40719979c7d4 100644 --- a/rerun_cpp/src/rerun/blueprint/components/.gitattributes +++ b/rerun_cpp/src/rerun/blueprint/components/.gitattributes @@ -41,7 +41,5 @@ space_view_maximized.cpp linguist-generated=true space_view_maximized.hpp linguist-generated=true space_view_origin.cpp linguist-generated=true space_view_origin.hpp linguist-generated=true -viewport_layout.cpp linguist-generated=true -viewport_layout.hpp linguist-generated=true visible.cpp linguist-generated=true visible.hpp linguist-generated=true diff --git a/rerun_cpp/src/rerun/blueprint/components/included_space_view.hpp b/rerun_cpp/src/rerun/blueprint/components/included_space_view.hpp index 03fbeb2ee20d..401f17fe69a0 100644 --- a/rerun_cpp/src/rerun/blueprint/components/included_space_view.hpp +++ b/rerun_cpp/src/rerun/blueprint/components/included_space_view.hpp @@ -21,29 +21,28 @@ namespace rerun::blueprint::components { /// /// Unstable. Used for the ongoing blueprint experimentations. struct IncludedSpaceView { - rerun::datatypes::Uuid space_view_ids; + rerun::datatypes::Uuid space_view_id; public: IncludedSpaceView() = default; - IncludedSpaceView(rerun::datatypes::Uuid space_view_ids_) - : space_view_ids(space_view_ids_) {} + IncludedSpaceView(rerun::datatypes::Uuid space_view_id_) : space_view_id(space_view_id_) {} - IncludedSpaceView& operator=(rerun::datatypes::Uuid space_view_ids_) { - space_view_ids = space_view_ids_; + IncludedSpaceView& operator=(rerun::datatypes::Uuid space_view_id_) { + space_view_id = space_view_id_; return *this; } - IncludedSpaceView(std::array bytes_) : space_view_ids(bytes_) {} + IncludedSpaceView(std::array bytes_) : space_view_id(bytes_) {} IncludedSpaceView& operator=(std::array bytes_) { - space_view_ids = bytes_; + space_view_id = bytes_; return *this; } /// Cast to the underlying Uuid datatype operator rerun::datatypes::Uuid() const { - return space_view_ids; + return space_view_id; } }; } // namespace rerun::blueprint::components diff --git a/rerun_cpp/src/rerun/blueprint/components/space_view_maximized.cpp b/rerun_cpp/src/rerun/blueprint/components/space_view_maximized.cpp index 8c5b43f1cc7e..245206f2539c 100644 --- a/rerun_cpp/src/rerun/blueprint/components/space_view_maximized.cpp +++ b/rerun_cpp/src/rerun/blueprint/components/space_view_maximized.cpp @@ -21,15 +21,14 @@ namespace rerun { arrow::FixedSizeListBuilder* builder, const blueprint::components::SpaceViewMaximized* elements, size_t num_elements ) { - (void)builder; - (void)elements; - (void)num_elements; - if (true) { - return rerun::Error( - ErrorCode::NotImplemented, - "TODO(andreas) Handle nullable extensions" - ); - } + static_assert( + sizeof(rerun::datatypes::Uuid) == sizeof(blueprint::components::SpaceViewMaximized) + ); + RR_RETURN_NOT_OK(Loggable::fill_arrow_array_builder( + builder, + reinterpret_cast(elements), + num_elements + )); return Error::ok(); } diff --git a/rerun_cpp/src/rerun/blueprint/components/space_view_maximized.hpp b/rerun_cpp/src/rerun/blueprint/components/space_view_maximized.hpp index 3a47a74e284e..f3d5579b4a94 100644 --- a/rerun_cpp/src/rerun/blueprint/components/space_view_maximized.hpp +++ b/rerun_cpp/src/rerun/blueprint/components/space_view_maximized.hpp @@ -9,7 +9,6 @@ #include #include #include -#include namespace arrow { class Array; @@ -22,15 +21,14 @@ namespace rerun::blueprint::components { /// /// Unstable. Used for the ongoing blueprint experimentations. struct SpaceViewMaximized { - std::optional space_view_id; + rerun::datatypes::Uuid space_view_id; public: SpaceViewMaximized() = default; - SpaceViewMaximized(std::optional space_view_id_) - : space_view_id(space_view_id_) {} + SpaceViewMaximized(rerun::datatypes::Uuid space_view_id_) : space_view_id(space_view_id_) {} - SpaceViewMaximized& operator=(std::optional space_view_id_) { + SpaceViewMaximized& operator=(rerun::datatypes::Uuid space_view_id_) { space_view_id = space_view_id_; return *this; } @@ -43,7 +41,7 @@ namespace rerun::blueprint::components { } /// Cast to the underlying Uuid datatype - operator std::optional() const { + operator rerun::datatypes::Uuid() const { return space_view_id; } }; diff --git a/rerun_cpp/src/rerun/blueprint/components/viewport_layout.cpp b/rerun_cpp/src/rerun/blueprint/components/viewport_layout.cpp deleted file mode 100644 index 26e7fbc47157..000000000000 --- a/rerun_cpp/src/rerun/blueprint/components/viewport_layout.cpp +++ /dev/null @@ -1,70 +0,0 @@ -// DO NOT EDIT! This file was auto-generated by crates/re_types_builder/src/codegen/cpp/mod.rs -// Based on "crates/re_types/definitions/rerun/blueprint/components/viewport_layout.fbs". - -#include "viewport_layout.hpp" - -#include -#include - -namespace rerun::blueprint::components {} - -namespace rerun { - const std::shared_ptr& - Loggable::arrow_datatype() { - static const auto datatype = arrow::list(arrow::field("item", arrow::uint8(), false)); - return datatype; - } - - rerun::Error Loggable::fill_arrow_array_builder( - arrow::ListBuilder* builder, const blueprint::components::ViewportLayout* 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 value_builder = static_cast(builder->value_builder()); - ARROW_RETURN_NOT_OK(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(builder->Append()); - ARROW_RETURN_NOT_OK(value_builder->AppendValues( - element.tree.data(), - static_cast(element.tree.size()), - nullptr - )); - } - - return Error::ok(); - } - - Result> Loggable::to_arrow( - const blueprint::components::ViewportLayout* 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; - } -} // namespace rerun diff --git a/rerun_cpp/src/rerun/blueprint/components/viewport_layout.hpp b/rerun_cpp/src/rerun/blueprint/components/viewport_layout.hpp deleted file mode 100644 index d62f3d9cf142..000000000000 --- a/rerun_cpp/src/rerun/blueprint/components/viewport_layout.hpp +++ /dev/null @@ -1,61 +0,0 @@ -// DO NOT EDIT! This file was auto-generated by crates/re_types_builder/src/codegen/cpp/mod.rs -// Based on "crates/re_types/definitions/rerun/blueprint/components/viewport_layout.fbs". - -#pragma once - -#include "../../collection.hpp" -#include "../../result.hpp" - -#include -#include -#include - -namespace arrow { - class Array; - class DataType; - class ListBuilder; -} // namespace arrow - -namespace rerun::blueprint::components { - /// **Component**: The layouts of all the space views. - /// - /// Unstable. Used for the ongoing blueprint experimentations. - struct ViewportLayout { - rerun::Collection tree; - - public: - ViewportLayout() = default; - - ViewportLayout(rerun::Collection tree_) : tree(std::move(tree_)) {} - - ViewportLayout& operator=(rerun::Collection tree_) { - tree = std::move(tree_); - return *this; - } - }; -} // namespace rerun::blueprint::components - -namespace rerun { - template - struct Loggable; - - /// \private - template <> - struct Loggable { - static constexpr const char Name[] = "rerun.blueprint.components.ViewportLayout"; - - /// Returns the arrow data type this type corresponds to. - static const std::shared_ptr& arrow_datatype(); - - /// Fills an arrow array builder with an array of this type. - static rerun::Error fill_arrow_array_builder( - arrow::ListBuilder* builder, const blueprint::components::ViewportLayout* elements, - size_t num_elements - ); - - /// Serializes an array of `rerun::blueprint:: components::ViewportLayout` into an arrow array. - static Result> to_arrow( - const blueprint::components::ViewportLayout* instances, size_t num_instances - ); - }; -} // namespace rerun diff --git a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/viewport_blueprint.py b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/viewport_blueprint.py index d97ecf8a3c13..537985c01a84 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/viewport_blueprint.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/viewport_blueprint.py @@ -25,7 +25,6 @@ def __init__( self: Any, space_views: datatypes.UuidArrayLike, *, - layout: blueprint_components.ViewportLayoutLike | None = None, root_container: datatypes.UuidLike | None = None, maximized: datatypes.UuidLike | None = None, auto_layout: blueprint_components.AutoLayoutLike | None = None, @@ -38,8 +37,6 @@ def __init__( ---------- space_views: All of the space-views that belong to the viewport. - layout: - The layout of the space-views root_container: The layout of the space-views maximized: @@ -47,7 +44,8 @@ def __init__( auto_layout: Whether the viewport layout is determined automatically. - Set to `false` the first time the user messes around with the viewport blueprint. + If `true`, the container layout will be reset whenever a new space view is added or removed. + This defaults to `false` and is automatically set to `false` when there is user determined layout. auto_space_views: Whether or not space views should be created automatically. @@ -57,7 +55,6 @@ def __init__( with catch_and_log_exceptions(context=self.__class__.__name__): self.__attrs_init__( space_views=space_views, - layout=layout, root_container=root_container, maximized=maximized, auto_layout=auto_layout, @@ -70,7 +67,6 @@ def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( space_views=None, # type: ignore[arg-type] - layout=None, # type: ignore[arg-type] root_container=None, # type: ignore[arg-type] maximized=None, # type: ignore[arg-type] auto_layout=None, # type: ignore[arg-type] @@ -92,15 +88,6 @@ def _clear(cls) -> ViewportBlueprint: # # (Docstring intentionally commented out to hide this field from the docs) - layout: blueprint_components.ViewportLayoutBatch | None = field( - metadata={"component": "optional"}, - default=None, - converter=blueprint_components.ViewportLayoutBatch._optional, # type: ignore[misc] - ) - # The layout of the space-views - # - # (Docstring intentionally commented out to hide this field from the docs) - root_container: blueprint_components.RootContainerBatch | None = field( metadata={"component": "optional"}, default=None, @@ -126,7 +113,8 @@ def _clear(cls) -> ViewportBlueprint: ) # Whether the viewport layout is determined automatically. # - # Set to `false` the first time the user messes around with the viewport blueprint. + # If `true`, the container layout will be reset whenever a new space view is added or removed. + # This defaults to `false` and is automatically set to `false` when there is user determined layout. # # (Docstring intentionally commented out to hide this field from the docs) diff --git a/rerun_py/rerun_sdk/rerun/blueprint/components/.gitattributes b/rerun_py/rerun_sdk/rerun/blueprint/components/.gitattributes index c34e9e9fb8c9..811e3c4fa2b3 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/components/.gitattributes +++ b/rerun_py/rerun_sdk/rerun/blueprint/components/.gitattributes @@ -22,5 +22,4 @@ row_shares.py linguist-generated=true space_view_class.py linguist-generated=true space_view_maximized.py linguist-generated=true space_view_origin.py linguist-generated=true -viewport_layout.py linguist-generated=true visible.py linguist-generated=true diff --git a/rerun_py/rerun_sdk/rerun/blueprint/components/__init__.py b/rerun_py/rerun_sdk/rerun/blueprint/components/__init__.py index c6d5974556d7..a0f0cc5e59c6 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/components/__init__.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/components/__init__.py @@ -76,13 +76,6 @@ ) from .space_view_maximized import SpaceViewMaximized, SpaceViewMaximizedBatch, SpaceViewMaximizedType from .space_view_origin import SpaceViewOrigin, SpaceViewOriginBatch, SpaceViewOriginType -from .viewport_layout import ( - ViewportLayout, - ViewportLayoutArrayLike, - ViewportLayoutBatch, - ViewportLayoutLike, - ViewportLayoutType, -) from .visible import Visible, VisibleArrayLike, VisibleBatch, VisibleLike, VisibleType __all__ = [ @@ -176,11 +169,6 @@ "SpaceViewOrigin", "SpaceViewOriginBatch", "SpaceViewOriginType", - "ViewportLayout", - "ViewportLayoutArrayLike", - "ViewportLayoutBatch", - "ViewportLayoutLike", - "ViewportLayoutType", "Visible", "VisibleArrayLike", "VisibleBatch", diff --git a/rerun_py/rerun_sdk/rerun/blueprint/components/auto_layout.py b/rerun_py/rerun_sdk/rerun/blueprint/components/auto_layout.py index fef9a267ffcd..a53b953a6741 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/components/auto_layout.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/components/auto_layout.py @@ -5,18 +5,19 @@ from __future__ import annotations -from typing import Any, Sequence, Union +from typing import TYPE_CHECKING, Any, Sequence, Union import pyarrow as pa from attrs import define, field from ..._baseclasses import BaseBatch, BaseExtensionType, ComponentBatchMixin +from .auto_layout_ext import AutoLayoutExt __all__ = ["AutoLayout", "AutoLayoutArrayLike", "AutoLayoutBatch", "AutoLayoutLike", "AutoLayoutType"] @define(init=False) -class AutoLayout: +class AutoLayout(AutoLayoutExt): """ **Component**: Whether the viewport layout is determined automatically. @@ -32,7 +33,11 @@ def __init__(self: Any, auto_layout: AutoLayoutLike): auto_layout: bool = field(converter=bool) -AutoLayoutLike = AutoLayout +if TYPE_CHECKING: + AutoLayoutLike = Union[AutoLayout, bool] +else: + AutoLayoutLike = Any + AutoLayoutArrayLike = Union[ AutoLayout, Sequence[AutoLayoutLike], @@ -51,4 +56,4 @@ class AutoLayoutBatch(BaseBatch[AutoLayoutArrayLike], ComponentBatchMixin): @staticmethod def _native_to_pa_array(data: AutoLayoutArrayLike, data_type: pa.DataType) -> pa.Array: - raise NotImplementedError # You need to implement native_to_pa_array_override in auto_layout_ext.py + return AutoLayoutExt.native_to_pa_array_override(data, data_type) diff --git a/rerun_py/rerun_sdk/rerun/blueprint/components/auto_layout_ext.py b/rerun_py/rerun_sdk/rerun/blueprint/components/auto_layout_ext.py new file mode 100644 index 000000000000..b228e2bdc11c --- /dev/null +++ b/rerun_py/rerun_sdk/rerun/blueprint/components/auto_layout_ext.py @@ -0,0 +1,18 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + +import numpy as np +import pyarrow as pa + +if TYPE_CHECKING: + from . import AutoLayoutArrayLike + + +class AutoLayoutExt: + """Extension for [AutoLayout][rerun.components.AutoLayout].""" + + @staticmethod + def native_to_pa_array_override(data: AutoLayoutArrayLike, data_type: pa.DataType) -> pa.Array: + array = np.asarray(data, dtype=np.bool_).flatten() + return pa.array(array, type=data_type) diff --git a/rerun_py/rerun_sdk/rerun/blueprint/components/auto_space_views.py b/rerun_py/rerun_sdk/rerun/blueprint/components/auto_space_views.py index de4d337dca5f..f3205556c56f 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/components/auto_space_views.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/components/auto_space_views.py @@ -5,12 +5,13 @@ from __future__ import annotations -from typing import Any, Sequence, Union +from typing import TYPE_CHECKING, Any, Sequence, Union import pyarrow as pa from attrs import define, field from ..._baseclasses import BaseBatch, BaseExtensionType, ComponentBatchMixin +from .auto_space_views_ext import AutoSpaceViewsExt __all__ = [ "AutoSpaceViews", @@ -22,7 +23,7 @@ @define(init=False) -class AutoSpaceViews: +class AutoSpaceViews(AutoSpaceViewsExt): """ **Component**: Whether or not space views should be created automatically. @@ -38,7 +39,11 @@ def __init__(self: Any, auto_space_views: AutoSpaceViewsLike): auto_space_views: bool = field(converter=bool) -AutoSpaceViewsLike = AutoSpaceViews +if TYPE_CHECKING: + AutoSpaceViewsLike = Union[AutoSpaceViews, bool] +else: + AutoSpaceViewsLike = Any + AutoSpaceViewsArrayLike = Union[ AutoSpaceViews, Sequence[AutoSpaceViewsLike], @@ -57,4 +62,4 @@ class AutoSpaceViewsBatch(BaseBatch[AutoSpaceViewsArrayLike], ComponentBatchMixi @staticmethod def _native_to_pa_array(data: AutoSpaceViewsArrayLike, data_type: pa.DataType) -> pa.Array: - raise NotImplementedError # You need to implement native_to_pa_array_override in auto_space_views_ext.py + return AutoSpaceViewsExt.native_to_pa_array_override(data, data_type) diff --git a/rerun_py/rerun_sdk/rerun/blueprint/components/auto_space_views_ext.py b/rerun_py/rerun_sdk/rerun/blueprint/components/auto_space_views_ext.py new file mode 100644 index 000000000000..db539487e976 --- /dev/null +++ b/rerun_py/rerun_sdk/rerun/blueprint/components/auto_space_views_ext.py @@ -0,0 +1,18 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + +import numpy as np +import pyarrow as pa + +if TYPE_CHECKING: + from . import AutoSpaceViewsArrayLike + + +class AutoSpaceViewsExt: + """Extension for [AutoSpaceViews][rerun.components.AutoSpaceViews].""" + + @staticmethod + def native_to_pa_array_override(data: AutoSpaceViewsArrayLike, data_type: pa.DataType) -> pa.Array: + array = np.asarray(data, dtype=np.bool_).flatten() + return pa.array(array, type=data_type) diff --git a/rerun_py/rerun_sdk/rerun/blueprint/components/viewport_layout.py b/rerun_py/rerun_sdk/rerun/blueprint/components/viewport_layout.py deleted file mode 100644 index 25eb7beb00d6..000000000000 --- a/rerun_py/rerun_sdk/rerun/blueprint/components/viewport_layout.py +++ /dev/null @@ -1,71 +0,0 @@ -# DO NOT EDIT! This file was auto-generated by crates/re_types_builder/src/codegen/python/mod.rs -# Based on "crates/re_types/definitions/rerun/blueprint/components/viewport_layout.fbs". - -# You can extend this class by creating a "ViewportLayoutExt" class in "viewport_layout_ext.py". - -from __future__ import annotations - -from typing import Any, Sequence, Union - -import numpy as np -import numpy.typing as npt -import pyarrow as pa -from attrs import define, field - -from ..._baseclasses import BaseBatch, BaseExtensionType, ComponentBatchMixin -from ..._converters import ( - to_np_uint8, -) - -__all__ = [ - "ViewportLayout", - "ViewportLayoutArrayLike", - "ViewportLayoutBatch", - "ViewportLayoutLike", - "ViewportLayoutType", -] - - -@define(init=False) -class ViewportLayout: - """ - **Component**: The layouts of all the space views. - - Unstable. Used for the ongoing blueprint experimentations. - """ - - def __init__(self: Any, tree: ViewportLayoutLike): - """Create a new instance of the ViewportLayout component.""" - - # You can define your own __init__ function as a member of ViewportLayoutExt in viewport_layout_ext.py - self.__attrs_init__(tree=tree) - - tree: npt.NDArray[np.uint8] = field(converter=to_np_uint8) - - def __array__(self, dtype: npt.DTypeLike = None) -> npt.NDArray[Any]: - # You can define your own __array__ function as a member of ViewportLayoutExt in viewport_layout_ext.py - return np.asarray(self.tree, dtype=dtype) - - -ViewportLayoutLike = ViewportLayout -ViewportLayoutArrayLike = Union[ - ViewportLayout, - Sequence[ViewportLayoutLike], -] - - -class ViewportLayoutType(BaseExtensionType): - _TYPE_NAME: str = "rerun.blueprint.components.ViewportLayout" - - def __init__(self) -> None: - pa.ExtensionType.__init__( - self, pa.list_(pa.field("item", pa.uint8(), nullable=False, metadata={})), self._TYPE_NAME - ) - - -class ViewportLayoutBatch(BaseBatch[ViewportLayoutArrayLike], ComponentBatchMixin): - _ARROW_TYPE = ViewportLayoutType() - - @staticmethod - def _native_to_pa_array(data: ViewportLayoutArrayLike, data_type: pa.DataType) -> pa.Array: - raise NotImplementedError # You need to implement native_to_pa_array_override in viewport_layout_ext.py diff --git a/rerun_py/tests/unit/test_viewport_blueprint.py b/rerun_py/tests/unit/test_viewport_blueprint.py index 64555900f142..a702271d6c71 100644 --- a/rerun_py/tests/unit/test_viewport_blueprint.py +++ b/rerun_py/tests/unit/test_viewport_blueprint.py @@ -3,54 +3,59 @@ import itertools from rerun.blueprint.archetypes.viewport_blueprint import ViewportBlueprint +from rerun.blueprint.components.auto_layout import AutoLayoutBatch +from rerun.blueprint.components.auto_space_views import AutoSpaceViewsBatch from rerun.blueprint.components.included_space_view import IncludedSpaceViewBatch +from rerun.blueprint.components.root_container import RootContainerBatch +from rerun.blueprint.components.space_view_maximized import SpaceViewMaximizedBatch -from .common_arrays import none_empty_or_value, uuids_arrays - -# TODO(andreas): We're obviously nowhere near done with this. +from .common_arrays import none_empty_or_value, uuid_bytes0, uuid_bytes1, uuids_arrays def test_viewport_blueprint() -> None: space_views_arrays = uuids_arrays - # layout_arrays = [] - # root_container_arrays = [] - # maximized_arrays = [] - # auto_layout_arrays = [] - # auto_space_views_arrays = [] + root_container_arrays = [ + None, + uuid_bytes0, + ] + maximized_arrays = [ + None, + uuid_bytes1, + ] + auto_layout_arrays = [None, True] + auto_space_views_arrays = [None, False] all_arrays = itertools.zip_longest( space_views_arrays, - # layout_arrays, - # root_container_arrays, - # maximized_arrays, - # auto_layout_arrays, - # auto_space_views_arrays, + root_container_arrays, + maximized_arrays, + auto_layout_arrays, + auto_space_views_arrays, ) - # for space_views, layout, root_container, maximized, auto_layout, auto_space_views in all_arrays: - for (space_views,) in all_arrays: - # space_views = space_views if space_views is not None else space_views_arrays[-1] + for space_views, root_container, maximized, auto_layout, auto_space_view in all_arrays: + space_views = space_views if space_views is not None else space_views_arrays[-1] print( "rr.ViewportBlueprint(\n", f" space_views={space_views!r}\n", - # f" layout={layout!r}\n", - # f" root_container={root_container!r}\n", - # f" maximized={maximized!r}\n", - # f" auto_layout={auto_layout!r}\n", - # f" auto_space_views={auto_space_views!r}\n", + f" root_container={root_container!r}\n", + f" maximized={maximized!r}\n", + f" auto_layout={auto_layout!r}\n", + f" auto_space_views={auto_space_view!r}\n", ")", ) arch = ViewportBlueprint( space_views, - # layout=layout, - # root_container=root_container, - # maximized=maximized, - # auto_layout=auto_layout, - # auto_space_views=auto_space_views, + root_container=root_container, + maximized=maximized, + auto_layout=auto_layout, + auto_space_views=auto_space_view, ) print(f"{arch}\n") - assert arch.space_views == IncludedSpaceViewBatch._optional( - none_empty_or_value(arch.space_views, uuids_arrays[-1]) - ) + assert arch.space_views == IncludedSpaceViewBatch._optional(none_empty_or_value(space_views, uuids_arrays[-1])) + assert arch.root_container == RootContainerBatch._optional(none_empty_or_value(root_container, uuid_bytes0)) + assert arch.maximized == SpaceViewMaximizedBatch._optional(none_empty_or_value(maximized, uuid_bytes1)) + assert arch.auto_layout == AutoLayoutBatch._optional(none_empty_or_value(auto_layout, True)) + assert arch.auto_space_views == AutoSpaceViewsBatch._optional(none_empty_or_value(auto_space_view, False))