From e39fad142a3b5ce9cabfc8580f3782eef27190a6 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Wed, 27 Nov 2024 14:45:37 +0100 Subject: [PATCH 01/29] first modelling of LineGrid3D --- .../rerun/blueprint/archetypes.fbs | 1 + .../blueprint/archetypes/line_grid_3d.fbs | 30 ++ .../rerun/blueprint/components.fbs | 3 + .../blueprint/components/grid_spacing.fbs | 12 + .../components/plane_orientation.fbs | 16 + .../rerun/blueprint/components/ui_radius.fbs | 12 + .../src/blueprint/archetypes/.gitattributes | 1 + .../src/blueprint/archetypes/line_grid3d.rs | 313 ++++++++++++++++++ .../re_types/src/blueprint/archetypes/mod.rs | 2 + .../src/blueprint/components/.gitattributes | 3 + .../src/blueprint/components/grid_spacing.rs | 116 +++++++ .../re_types/src/blueprint/components/mod.rs | 6 + .../blueprint/components/plane_orientation.rs | 167 ++++++++++ .../src/blueprint/components/ui_radius.rs | 116 +++++++ .../src/blueprint/validation_gen/mod.rs | 6 + crates/viewer/re_viewer/src/reflection/mod.rs | 54 +++ rerun_cpp/src/rerun/blueprint/archetypes.hpp | 1 + .../rerun/blueprint/archetypes/.gitattributes | 2 + .../blueprint/archetypes/line_grid3d.cpp | 53 +++ .../blueprint/archetypes/line_grid3d.hpp | 121 +++++++ rerun_cpp/src/rerun/blueprint/components.hpp | 3 + .../rerun/blueprint/components/.gitattributes | 4 + .../blueprint/components/grid_spacing.hpp | 74 +++++ .../components/plane_orientation.cpp | 61 ++++ .../components/plane_orientation.hpp | 60 ++++ .../rerun/blueprint/components/ui_radius.hpp | 74 +++++ .../rerun/blueprint/archetypes/.gitattributes | 1 + .../rerun/blueprint/archetypes/__init__.py | 2 + .../rerun/blueprint/archetypes/line_grid3d.py | 142 ++++++++ .../rerun/blueprint/components/.gitattributes | 3 + .../rerun/blueprint/components/__init__.py | 11 + .../blueprint/components/grid_spacing.py | 32 ++ .../blueprint/components/plane_orientation.py | 71 ++++ .../rerun/blueprint/components/ui_radius.py | 32 ++ 34 files changed, 1605 insertions(+) create mode 100644 crates/store/re_types/definitions/rerun/blueprint/archetypes/line_grid_3d.fbs create mode 100644 crates/store/re_types/definitions/rerun/blueprint/components/grid_spacing.fbs create mode 100644 crates/store/re_types/definitions/rerun/blueprint/components/plane_orientation.fbs create mode 100644 crates/store/re_types/definitions/rerun/blueprint/components/ui_radius.fbs create mode 100644 crates/store/re_types/src/blueprint/archetypes/line_grid3d.rs create mode 100644 crates/store/re_types/src/blueprint/components/grid_spacing.rs create mode 100644 crates/store/re_types/src/blueprint/components/plane_orientation.rs create mode 100644 crates/store/re_types/src/blueprint/components/ui_radius.rs create mode 100644 rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.cpp create mode 100644 rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.hpp create mode 100644 rerun_cpp/src/rerun/blueprint/components/grid_spacing.hpp create mode 100644 rerun_cpp/src/rerun/blueprint/components/plane_orientation.cpp create mode 100644 rerun_cpp/src/rerun/blueprint/components/plane_orientation.hpp create mode 100644 rerun_cpp/src/rerun/blueprint/components/ui_radius.hpp create mode 100644 rerun_py/rerun_sdk/rerun/blueprint/archetypes/line_grid3d.py create mode 100644 rerun_py/rerun_sdk/rerun/blueprint/components/grid_spacing.py create mode 100644 rerun_py/rerun_sdk/rerun/blueprint/components/plane_orientation.py create mode 100644 rerun_py/rerun_sdk/rerun/blueprint/components/ui_radius.py diff --git a/crates/store/re_types/definitions/rerun/blueprint/archetypes.fbs b/crates/store/re_types/definitions/rerun/blueprint/archetypes.fbs index 47eb842fc7c0..7ca46166ee56 100644 --- a/crates/store/re_types/definitions/rerun/blueprint/archetypes.fbs +++ b/crates/store/re_types/definitions/rerun/blueprint/archetypes.fbs @@ -3,6 +3,7 @@ include "./archetypes/background.fbs"; include "./archetypes/container_blueprint.fbs"; include "./archetypes/dataframe_query.fbs"; +include "./archetypes/line_grid_3d.fbs"; include "./archetypes/map_background.fbs"; include "./archetypes/map_zoom.fbs"; include "./archetypes/panel_blueprint.fbs"; diff --git a/crates/store/re_types/definitions/rerun/blueprint/archetypes/line_grid_3d.fbs b/crates/store/re_types/definitions/rerun/blueprint/archetypes/line_grid_3d.fbs new file mode 100644 index 000000000000..4e2b1770ff55 --- /dev/null +++ b/crates/store/re_types/definitions/rerun/blueprint/archetypes/line_grid_3d.fbs @@ -0,0 +1,30 @@ +namespace rerun.blueprint.archetypes; + +/// Configuration for the 3D line grid. +table LineGrid3D ( + "attr.rerun.scope": "blueprint" +) { + /// Whether the grid is visible. + /// + /// Defaults to true. + visible: rerun.blueprint.components.Visible ("attr.rerun.component_optional", nullable, order: 1000); + + /// Space between grid lines spacing of one line to the next in scene units. + spacing: rerun.blueprint.components.GridSpacing ("attr.rerun.component_optional", nullable, order: 2000); + + /// How thick the lines should be in ui units. + /// + /// Default is 0.5 ui unit. + line_radius: rerun.blueprint.components.UiRadius ("attr.rerun.component_optional", nullable, order: 3000); + + /// Color used for the grid. + /// + /// Transparency via alpha channel is supported. + /// Defaults to a slightly transparent light gray. + color: rerun.components.Color ("attr.rerun.component_optional", nullable, order: 4000); + + /// How the grid is oriented. + /// + /// Defaults to whatever plane is determined as the down plane by view coordinates if present. + orientation: rerun.blueprint.components.PlaneOrientation ("attr.rerun.component_optional", nullable, order: 5000); +} diff --git a/crates/store/re_types/definitions/rerun/blueprint/components.fbs b/crates/store/re_types/definitions/rerun/blueprint/components.fbs index f52c3ae986f1..345cd4c113df 100644 --- a/crates/store/re_types/definitions/rerun/blueprint/components.fbs +++ b/crates/store/re_types/definitions/rerun/blueprint/components.fbs @@ -12,11 +12,13 @@ include "./components/corner_2d.fbs"; include "./components/filter_by_range.fbs"; include "./components/filter_is_not_null.fbs"; include "./components/grid_columns.fbs"; +include "./components/grid_spacing.fbs"; include "./components/included_content.fbs"; include "./components/interactive.fbs"; include "./components/lock_range_during_zoom.fbs"; include "./components/map_provider.fbs"; include "./components/panel_state.fbs"; +include "./components/plane_orientation.fbs"; include "./components/query_expression.fbs"; include "./components/root_container.fbs"; include "./components/row_share.fbs"; @@ -26,6 +28,7 @@ include "./components/space_view_maximized.fbs"; include "./components/space_view_origin.fbs"; include "./components/tensor_dimension_index_slider.fbs"; include "./components/timeline_name.fbs"; +include "./components/ui_radius.fbs"; include "./components/view_fit.fbs"; include "./components/viewer_recommendation_hash.fbs"; include "./components/visible.fbs"; diff --git a/crates/store/re_types/definitions/rerun/blueprint/components/grid_spacing.fbs b/crates/store/re_types/definitions/rerun/blueprint/components/grid_spacing.fbs new file mode 100644 index 000000000000..47ee4e013035 --- /dev/null +++ b/crates/store/re_types/definitions/rerun/blueprint/components/grid_spacing.fbs @@ -0,0 +1,12 @@ +namespace rerun.blueprint.components; + +/// Space between grid lines of one line to the next in scene units. +table GridSpacing ( + "attr.python.aliases": "float", + "attr.python.array_aliases": "npt.ArrayLike", + "attr.rerun.scope": "blueprint", + "attr.rust.derive": "Default" +) { + /// Space between grid lines of one line to the next in scene units. + distance: rerun.datatypes.Float32 (order: 100); +} diff --git a/crates/store/re_types/definitions/rerun/blueprint/components/plane_orientation.fbs b/crates/store/re_types/definitions/rerun/blueprint/components/plane_orientation.fbs new file mode 100644 index 000000000000..424c3207d03e --- /dev/null +++ b/crates/store/re_types/definitions/rerun/blueprint/components/plane_orientation.fbs @@ -0,0 +1,16 @@ +namespace rerun.blueprint.components; + +/// Orientation of a 3D axis aligned plane. +enum PlaneOrientation: ubyte ( + "attr.rerun.scope": "blueprint" +) { + /// Invalid value. Won't show up in generated types. + Invalid = 0, + + /// Plane spanned by X and Z axis. + Xz (default), + /// Plane spanned by Y and Z axis. + Yz, + /// Plane spanned by X and Y axis. + Xy, +} diff --git a/crates/store/re_types/definitions/rerun/blueprint/components/ui_radius.fbs b/crates/store/re_types/definitions/rerun/blueprint/components/ui_radius.fbs new file mode 100644 index 000000000000..b511e3adb4d7 --- /dev/null +++ b/crates/store/re_types/definitions/rerun/blueprint/components/ui_radius.fbs @@ -0,0 +1,12 @@ +namespace rerun.blueprint.components; + +/// Like `Radius`, but in always in ui units. +table UiRadius ( + "attr.python.aliases": "float", + "attr.python.array_aliases": "npt.ArrayLike", + "attr.rerun.scope": "blueprint", + "attr.rust.derive": "Default" +) { + /// Radius in ui units. + radius: rerun.datatypes.Float32 (order: 100); +} diff --git a/crates/store/re_types/src/blueprint/archetypes/.gitattributes b/crates/store/re_types/src/blueprint/archetypes/.gitattributes index 158c53d4bb45..0053d35aa081 100644 --- a/crates/store/re_types/src/blueprint/archetypes/.gitattributes +++ b/crates/store/re_types/src/blueprint/archetypes/.gitattributes @@ -3,6 +3,7 @@ .gitattributes linguist-generated=true background.rs linguist-generated=true dataframe_query.rs linguist-generated=true +line_grid3d.rs linguist-generated=true map_background.rs linguist-generated=true map_zoom.rs linguist-generated=true mod.rs linguist-generated=true diff --git a/crates/store/re_types/src/blueprint/archetypes/line_grid3d.rs b/crates/store/re_types/src/blueprint/archetypes/line_grid3d.rs new file mode 100644 index 000000000000..2e43b993235b --- /dev/null +++ b/crates/store/re_types/src/blueprint/archetypes/line_grid3d.rs @@ -0,0 +1,313 @@ +// 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/blueprint/archetypes/line_grid_3d.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::ComponentName; +use ::re_types_core::SerializationResult; +use ::re_types_core::{ComponentBatch, MaybeOwnedComponentBatch}; +use ::re_types_core::{DeserializationError, DeserializationResult}; + +/// **Archetype**: Configuration for the 3D line grid. +#[derive(Clone, Debug)] +pub struct LineGrid3D { + /// Whether the grid is visible. + /// + /// Defaults to true. + pub visible: Option, + + /// Space between grid lines spacing of one line to the next in scene units. + pub spacing: Option, + + /// How thick the lines should be in ui units. + /// + /// Default is 0.5 ui unit. + pub line_radius: Option, + + /// Color used for the grid. + /// + /// Transparency via alpha channel is supported. + /// Defaults to a slightly transparent light gray. + pub color: Option, + + /// How the grid is oriented. + /// + /// Defaults to whatever plane is determined as the down plane by view coordinates if present. + pub orientation: Option, +} + +impl ::re_types_core::SizeBytes for LineGrid3D { + #[inline] + fn heap_size_bytes(&self) -> u64 { + self.visible.heap_size_bytes() + + self.spacing.heap_size_bytes() + + self.line_radius.heap_size_bytes() + + self.color.heap_size_bytes() + + self.orientation.heap_size_bytes() + } + + #[inline] + fn is_pod() -> bool { + >::is_pod() + && >::is_pod() + && >::is_pod() + && >::is_pod() + && >::is_pod() + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentName; 0usize]> = + once_cell::sync::Lazy::new(|| []); + +static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentName; 1usize]> = + once_cell::sync::Lazy::new(|| ["rerun.blueprint.components.LineGrid3DIndicator".into()]); + +static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentName; 5usize]> = + once_cell::sync::Lazy::new(|| { + [ + "rerun.blueprint.components.Visible".into(), + "rerun.blueprint.components.GridSpacing".into(), + "rerun.blueprint.components.UiRadius".into(), + "rerun.components.Color".into(), + "rerun.blueprint.components.PlaneOrientation".into(), + ] + }); + +static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentName; 6usize]> = + once_cell::sync::Lazy::new(|| { + [ + "rerun.blueprint.components.LineGrid3DIndicator".into(), + "rerun.blueprint.components.Visible".into(), + "rerun.blueprint.components.GridSpacing".into(), + "rerun.blueprint.components.UiRadius".into(), + "rerun.components.Color".into(), + "rerun.blueprint.components.PlaneOrientation".into(), + ] + }); + +impl LineGrid3D { + /// The total number of components in the archetype: 0 required, 1 recommended, 5 optional + pub const NUM_COMPONENTS: usize = 6usize; +} + +/// Indicator component for the [`LineGrid3D`] [`::re_types_core::Archetype`] +pub type LineGrid3DIndicator = ::re_types_core::GenericIndicatorComponent; + +impl ::re_types_core::Archetype for LineGrid3D { + type Indicator = LineGrid3DIndicator; + + #[inline] + fn name() -> ::re_types_core::ArchetypeName { + "rerun.blueprint.archetypes.LineGrid3D".into() + } + + #[inline] + fn display_name() -> &'static str { + "Line grid 3D" + } + + #[inline] + fn indicator() -> MaybeOwnedComponentBatch<'static> { + static INDICATOR: LineGrid3DIndicator = LineGrid3DIndicator::DEFAULT; + MaybeOwnedComponentBatch::Ref(&INDICATOR) + } + + #[inline] + fn required_components() -> ::std::borrow::Cow<'static, [ComponentName]> { + REQUIRED_COMPONENTS.as_slice().into() + } + + #[inline] + fn recommended_components() -> ::std::borrow::Cow<'static, [ComponentName]> { + RECOMMENDED_COMPONENTS.as_slice().into() + } + + #[inline] + fn optional_components() -> ::std::borrow::Cow<'static, [ComponentName]> { + OPTIONAL_COMPONENTS.as_slice().into() + } + + #[inline] + fn all_components() -> ::std::borrow::Cow<'static, [ComponentName]> { + ALL_COMPONENTS.as_slice().into() + } + + #[inline] + fn from_arrow2_components( + arrow_data: impl IntoIterator)>, + ) -> DeserializationResult { + re_tracing::profile_function!(); + use ::re_types_core::{Loggable as _, ResultExt as _}; + let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data + .into_iter() + .map(|(name, array)| (name.full_name(), array)) + .collect(); + let visible = if let Some(array) = arrays_by_name.get("rerun.blueprint.components.Visible") + { + ::from_arrow2_opt(&**array) + .with_context("rerun.blueprint.archetypes.LineGrid3D#visible")? + .into_iter() + .next() + .flatten() + } else { + None + }; + let spacing = + if let Some(array) = arrays_by_name.get("rerun.blueprint.components.GridSpacing") { + ::from_arrow2_opt(&**array) + .with_context("rerun.blueprint.archetypes.LineGrid3D#spacing")? + .into_iter() + .next() + .flatten() + } else { + None + }; + let line_radius = + if let Some(array) = arrays_by_name.get("rerun.blueprint.components.UiRadius") { + ::from_arrow2_opt(&**array) + .with_context("rerun.blueprint.archetypes.LineGrid3D#line_radius")? + .into_iter() + .next() + .flatten() + } else { + None + }; + let color = if let Some(array) = arrays_by_name.get("rerun.components.Color") { + ::from_arrow2_opt(&**array) + .with_context("rerun.blueprint.archetypes.LineGrid3D#color")? + .into_iter() + .next() + .flatten() + } else { + None + }; + let orientation = if let Some(array) = + arrays_by_name.get("rerun.blueprint.components.PlaneOrientation") + { + ::from_arrow2_opt(&**array) + .with_context("rerun.blueprint.archetypes.LineGrid3D#orientation")? + .into_iter() + .next() + .flatten() + } else { + None + }; + Ok(Self { + visible, + spacing, + line_radius, + color, + orientation, + }) + } +} + +impl ::re_types_core::AsComponents for LineGrid3D { + fn as_component_batches(&self) -> Vec> { + re_tracing::profile_function!(); + use ::re_types_core::Archetype as _; + [ + Some(Self::indicator()), + self.visible + .as_ref() + .map(|comp| (comp as &dyn ComponentBatch).into()), + self.spacing + .as_ref() + .map(|comp| (comp as &dyn ComponentBatch).into()), + self.line_radius + .as_ref() + .map(|comp| (comp as &dyn ComponentBatch).into()), + self.color + .as_ref() + .map(|comp| (comp as &dyn ComponentBatch).into()), + self.orientation + .as_ref() + .map(|comp| (comp as &dyn ComponentBatch).into()), + ] + .into_iter() + .flatten() + .collect() + } +} + +impl ::re_types_core::ArchetypeReflectionMarker for LineGrid3D {} + +impl LineGrid3D { + /// Create a new `LineGrid3D`. + #[inline] + pub fn new() -> Self { + Self { + visible: None, + spacing: None, + line_radius: None, + color: None, + orientation: None, + } + } + + /// Whether the grid is visible. + /// + /// Defaults to true. + #[inline] + pub fn with_visible( + mut self, + visible: impl Into, + ) -> Self { + self.visible = Some(visible.into()); + self + } + + /// Space between grid lines spacing of one line to the next in scene units. + #[inline] + pub fn with_spacing( + mut self, + spacing: impl Into, + ) -> Self { + self.spacing = Some(spacing.into()); + self + } + + /// How thick the lines should be in ui units. + /// + /// Default is 0.5 ui unit. + #[inline] + pub fn with_line_radius( + mut self, + line_radius: impl Into, + ) -> Self { + self.line_radius = Some(line_radius.into()); + self + } + + /// Color used for the grid. + /// + /// Transparency via alpha channel is supported. + /// Defaults to a slightly transparent light gray. + #[inline] + pub fn with_color(mut self, color: impl Into) -> Self { + self.color = Some(color.into()); + self + } + + /// How the grid is oriented. + /// + /// Defaults to whatever plane is determined as the down plane by view coordinates if present. + #[inline] + pub fn with_orientation( + mut self, + orientation: impl Into, + ) -> Self { + self.orientation = Some(orientation.into()); + self + } +} diff --git a/crates/store/re_types/src/blueprint/archetypes/mod.rs b/crates/store/re_types/src/blueprint/archetypes/mod.rs index 360c1b887939..4b5aa896e251 100644 --- a/crates/store/re_types/src/blueprint/archetypes/mod.rs +++ b/crates/store/re_types/src/blueprint/archetypes/mod.rs @@ -2,6 +2,7 @@ mod background; mod dataframe_query; +mod line_grid3d; mod map_background; mod map_zoom; mod plot_legend; @@ -17,6 +18,7 @@ mod visual_bounds2d; pub use self::background::Background; pub use self::dataframe_query::DataframeQuery; +pub use self::line_grid3d::LineGrid3D; pub use self::map_background::MapBackground; pub use self::map_zoom::MapZoom; pub use self::plot_legend::PlotLegend; diff --git a/crates/store/re_types/src/blueprint/components/.gitattributes b/crates/store/re_types/src/blueprint/components/.gitattributes index 4a1915dc979d..1abe730df77b 100644 --- a/crates/store/re_types/src/blueprint/components/.gitattributes +++ b/crates/store/re_types/src/blueprint/components/.gitattributes @@ -9,12 +9,14 @@ component_column_selector.rs linguist-generated=true corner2d.rs linguist-generated=true filter_by_range.rs linguist-generated=true filter_is_not_null.rs linguist-generated=true +grid_spacing.rs linguist-generated=true included_content.rs linguist-generated=true interactive.rs linguist-generated=true lock_range_during_zoom.rs linguist-generated=true map_provider.rs linguist-generated=true mod.rs linguist-generated=true panel_state.rs linguist-generated=true +plane_orientation.rs linguist-generated=true query_expression.rs linguist-generated=true row_share.rs linguist-generated=true selected_columns.rs linguist-generated=true @@ -22,6 +24,7 @@ space_view_class.rs linguist-generated=true space_view_origin.rs linguist-generated=true tensor_dimension_index_slider.rs linguist-generated=true timeline_name.rs linguist-generated=true +ui_radius.rs linguist-generated=true view_fit.rs linguist-generated=true viewer_recommendation_hash.rs linguist-generated=true visible.rs linguist-generated=true diff --git a/crates/store/re_types/src/blueprint/components/grid_spacing.rs b/crates/store/re_types/src/blueprint/components/grid_spacing.rs new file mode 100644 index 000000000000..9b6784df7107 --- /dev/null +++ b/crates/store/re_types/src/blueprint/components/grid_spacing.rs @@ -0,0 +1,116 @@ +// 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/blueprint/components/grid_spacing.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::ComponentName; +use ::re_types_core::SerializationResult; +use ::re_types_core::{ComponentBatch, MaybeOwnedComponentBatch}; +use ::re_types_core::{DeserializationError, DeserializationResult}; + +/// **Component**: Space between grid lines of one line to the next in scene units. +#[derive(Clone, Debug, Default)] +pub struct GridSpacing( + /// Space between grid lines of one line to the next in scene units. + pub crate::datatypes::Float32, +); + +impl ::re_types_core::SizeBytes for GridSpacing { + #[inline] + fn heap_size_bytes(&self) -> u64 { + self.0.heap_size_bytes() + } + + #[inline] + fn is_pod() -> bool { + ::is_pod() + } +} + +impl> From for GridSpacing { + fn from(v: T) -> Self { + Self(v.into()) + } +} + +impl std::borrow::Borrow for GridSpacing { + #[inline] + fn borrow(&self) -> &crate::datatypes::Float32 { + &self.0 + } +} + +impl std::ops::Deref for GridSpacing { + type Target = crate::datatypes::Float32; + + #[inline] + fn deref(&self) -> &crate::datatypes::Float32 { + &self.0 + } +} + +impl std::ops::DerefMut for GridSpacing { + #[inline] + fn deref_mut(&mut self) -> &mut crate::datatypes::Float32 { + &mut self.0 + } +} + +::re_types_core::macros::impl_into_cow!(GridSpacing); + +impl ::re_types_core::Loggable for GridSpacing { + #[inline] + fn arrow_datatype() -> arrow::datatypes::DataType { + crate::datatypes::Float32::arrow_datatype() + } + + fn to_arrow_opt<'a>( + data: impl IntoIterator>>>, + ) -> SerializationResult + where + Self: Clone + 'a, + { + crate::datatypes::Float32::to_arrow_opt(data.into_iter().map(|datum| { + datum.map(|datum| match datum.into() { + ::std::borrow::Cow::Borrowed(datum) => ::std::borrow::Cow::Borrowed(&datum.0), + ::std::borrow::Cow::Owned(datum) => ::std::borrow::Cow::Owned(datum.0), + }) + })) + } + + fn from_arrow2_opt( + arrow_data: &dyn arrow2::array::Array, + ) -> DeserializationResult>> + where + Self: Sized, + { + crate::datatypes::Float32::from_arrow2_opt(arrow_data) + .map(|v| v.into_iter().map(|v| v.map(Self)).collect()) + } + + #[inline] + fn from_arrow2(arrow_data: &dyn arrow2::array::Array) -> DeserializationResult> + where + Self: Sized, + { + crate::datatypes::Float32::from_arrow2(arrow_data) + .map(|v| v.into_iter().map(Self).collect()) + } +} + +impl ::re_types_core::Component for GridSpacing { + #[inline] + fn name() -> ComponentName { + "rerun.blueprint.components.GridSpacing".into() + } +} diff --git a/crates/store/re_types/src/blueprint/components/mod.rs b/crates/store/re_types/src/blueprint/components/mod.rs index a915957fd392..67077e11411d 100644 --- a/crates/store/re_types/src/blueprint/components/mod.rs +++ b/crates/store/re_types/src/blueprint/components/mod.rs @@ -12,6 +12,7 @@ mod filter_by_range; mod filter_by_range_ext; mod filter_is_not_null; mod filter_is_not_null_ext; +mod grid_spacing; mod included_content; mod interactive; mod interactive_ext; @@ -19,6 +20,7 @@ mod lock_range_during_zoom; mod map_provider; mod panel_state; mod panel_state_ext; +mod plane_orientation; mod query_expression; mod row_share; mod selected_columns; @@ -30,6 +32,7 @@ mod tensor_dimension_index_slider; mod tensor_dimension_index_slider_ext; mod timeline_name; mod timeline_name_ext; +mod ui_radius; mod view_fit; mod viewer_recommendation_hash; mod viewer_recommendation_hash_ext; @@ -48,11 +51,13 @@ pub use self::component_column_selector::ComponentColumnSelector; pub use self::corner2d::Corner2D; pub use self::filter_by_range::FilterByRange; pub use self::filter_is_not_null::FilterIsNotNull; +pub use self::grid_spacing::GridSpacing; pub use self::included_content::IncludedContent; pub use self::interactive::Interactive; pub use self::lock_range_during_zoom::LockRangeDuringZoom; pub use self::map_provider::MapProvider; pub use self::panel_state::PanelState; +pub use self::plane_orientation::PlaneOrientation; pub use self::query_expression::QueryExpression; pub use self::row_share::RowShare; pub use self::selected_columns::SelectedColumns; @@ -60,6 +65,7 @@ pub use self::space_view_class::SpaceViewClass; pub use self::space_view_origin::SpaceViewOrigin; pub use self::tensor_dimension_index_slider::TensorDimensionIndexSlider; pub use self::timeline_name::TimelineName; +pub use self::ui_radius::UiRadius; pub use self::view_fit::ViewFit; pub use self::viewer_recommendation_hash::ViewerRecommendationHash; pub use self::visible::Visible; diff --git a/crates/store/re_types/src/blueprint/components/plane_orientation.rs b/crates/store/re_types/src/blueprint/components/plane_orientation.rs new file mode 100644 index 000000000000..5795db5aaf56 --- /dev/null +++ b/crates/store/re_types/src/blueprint/components/plane_orientation.rs @@ -0,0 +1,167 @@ +// 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/blueprint/components/plane_orientation.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)] +#![allow(non_camel_case_types)] + +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**: Orientation of a 3D axis aligned plane. +#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Default)] +#[repr(u8)] +pub enum PlaneOrientation { + /// Plane spanned by X and Z axis. + #[default] + Xz = 1, + + /// Plane spanned by Y and Z axis. + Yz = 2, + + /// Plane spanned by X and Y axis. + Xy = 3, +} + +impl ::re_types_core::reflection::Enum for PlaneOrientation { + #[inline] + fn variants() -> &'static [Self] { + &[Self::Xz, Self::Yz, Self::Xy] + } + + #[inline] + fn docstring_md(self) -> &'static str { + match self { + Self::Xz => "Plane spanned by X and Z axis.", + Self::Yz => "Plane spanned by Y and Z axis.", + Self::Xy => "Plane spanned by X and Y axis.", + } + } +} + +impl ::re_types_core::SizeBytes for PlaneOrientation { + #[inline] + fn heap_size_bytes(&self) -> u64 { + 0 + } + + #[inline] + fn is_pod() -> bool { + true + } +} + +impl std::fmt::Display for PlaneOrientation { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Xz => write!(f, "Xz"), + Self::Yz => write!(f, "Yz"), + Self::Xy => write!(f, "Xy"), + } + } +} + +::re_types_core::macros::impl_into_cow!(PlaneOrientation); + +impl ::re_types_core::Loggable for PlaneOrientation { + #[inline] + fn arrow_datatype() -> arrow::datatypes::DataType { + #![allow(clippy::wildcard_imports)] + use arrow::datatypes::*; + DataType::UInt8 + } + + 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::{Loggable as _, ResultExt as _}; + use arrow::{array::*, buffer::*, datatypes::*}; + + #[allow(unused)] + fn as_array_ref(t: T) -> ArrayRef { + std::sync::Arc::new(t) as ArrayRef + } + 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| *datum as u8); + (datum.is_some(), datum) + }) + .unzip(); + let data0_validity: Option = { + let any_nones = somes.iter().any(|some| !*some); + any_nones.then(|| somes.into()) + }; + as_array_ref(PrimitiveArray::::new( + ScalarBuffer::from( + data0 + .into_iter() + .map(|v| v.unwrap_or_default()) + .collect::>(), + ), + data0_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(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.PlaneOrientation#enum")? + .into_iter() + .map(|opt| opt.copied()) + .map(|typ| match typ { + Some(1) => Ok(Some(Self::Xz)), + Some(2) => Ok(Some(Self::Yz)), + Some(3) => Ok(Some(Self::Xy)), + None => Ok(None), + Some(invalid) => Err(DeserializationError::missing_union_arm( + Self::arrow_datatype(), + "", + invalid as _, + )), + }) + .collect::>>>() + .with_context("rerun.blueprint.components.PlaneOrientation")?) + } +} + +impl ::re_types_core::Component for PlaneOrientation { + #[inline] + fn name() -> ComponentName { + "rerun.blueprint.components.PlaneOrientation".into() + } +} diff --git a/crates/store/re_types/src/blueprint/components/ui_radius.rs b/crates/store/re_types/src/blueprint/components/ui_radius.rs new file mode 100644 index 000000000000..4b8dc6539ad1 --- /dev/null +++ b/crates/store/re_types/src/blueprint/components/ui_radius.rs @@ -0,0 +1,116 @@ +// 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/blueprint/components/ui_radius.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::ComponentName; +use ::re_types_core::SerializationResult; +use ::re_types_core::{ComponentBatch, MaybeOwnedComponentBatch}; +use ::re_types_core::{DeserializationError, DeserializationResult}; + +/// **Component**: Like `Radius`, but in always in ui units. +#[derive(Clone, Debug, Default)] +pub struct UiRadius( + /// Radius in ui units. + pub crate::datatypes::Float32, +); + +impl ::re_types_core::SizeBytes for UiRadius { + #[inline] + fn heap_size_bytes(&self) -> u64 { + self.0.heap_size_bytes() + } + + #[inline] + fn is_pod() -> bool { + ::is_pod() + } +} + +impl> From for UiRadius { + fn from(v: T) -> Self { + Self(v.into()) + } +} + +impl std::borrow::Borrow for UiRadius { + #[inline] + fn borrow(&self) -> &crate::datatypes::Float32 { + &self.0 + } +} + +impl std::ops::Deref for UiRadius { + type Target = crate::datatypes::Float32; + + #[inline] + fn deref(&self) -> &crate::datatypes::Float32 { + &self.0 + } +} + +impl std::ops::DerefMut for UiRadius { + #[inline] + fn deref_mut(&mut self) -> &mut crate::datatypes::Float32 { + &mut self.0 + } +} + +::re_types_core::macros::impl_into_cow!(UiRadius); + +impl ::re_types_core::Loggable for UiRadius { + #[inline] + fn arrow_datatype() -> arrow::datatypes::DataType { + crate::datatypes::Float32::arrow_datatype() + } + + fn to_arrow_opt<'a>( + data: impl IntoIterator>>>, + ) -> SerializationResult + where + Self: Clone + 'a, + { + crate::datatypes::Float32::to_arrow_opt(data.into_iter().map(|datum| { + datum.map(|datum| match datum.into() { + ::std::borrow::Cow::Borrowed(datum) => ::std::borrow::Cow::Borrowed(&datum.0), + ::std::borrow::Cow::Owned(datum) => ::std::borrow::Cow::Owned(datum.0), + }) + })) + } + + fn from_arrow2_opt( + arrow_data: &dyn arrow2::array::Array, + ) -> DeserializationResult>> + where + Self: Sized, + { + crate::datatypes::Float32::from_arrow2_opt(arrow_data) + .map(|v| v.into_iter().map(|v| v.map(Self)).collect()) + } + + #[inline] + fn from_arrow2(arrow_data: &dyn arrow2::array::Array) -> DeserializationResult> + where + Self: Sized, + { + crate::datatypes::Float32::from_arrow2(arrow_data) + .map(|v| v.into_iter().map(Self).collect()) + } +} + +impl ::re_types_core::Component for UiRadius { + #[inline] + fn name() -> ComponentName { + "rerun.blueprint.components.UiRadius".into() + } +} diff --git a/crates/viewer/re_viewer/src/blueprint/validation_gen/mod.rs b/crates/viewer/re_viewer/src/blueprint/validation_gen/mod.rs index ac256bc847d4..9e9ad447ea97 100644 --- a/crates/viewer/re_viewer/src/blueprint/validation_gen/mod.rs +++ b/crates/viewer/re_viewer/src/blueprint/validation_gen/mod.rs @@ -9,11 +9,13 @@ pub use re_types::blueprint::components::ComponentColumnSelector; pub use re_types::blueprint::components::Corner2D; pub use re_types::blueprint::components::FilterByRange; pub use re_types::blueprint::components::FilterIsNotNull; +pub use re_types::blueprint::components::GridSpacing; pub use re_types::blueprint::components::IncludedContent; pub use re_types::blueprint::components::Interactive; pub use re_types::blueprint::components::LockRangeDuringZoom; pub use re_types::blueprint::components::MapProvider; pub use re_types::blueprint::components::PanelState; +pub use re_types::blueprint::components::PlaneOrientation; pub use re_types::blueprint::components::QueryExpression; pub use re_types::blueprint::components::RowShare; pub use re_types::blueprint::components::SelectedColumns; @@ -21,6 +23,7 @@ pub use re_types::blueprint::components::SpaceViewClass; pub use re_types::blueprint::components::SpaceViewOrigin; pub use re_types::blueprint::components::TensorDimensionIndexSlider; pub use re_types::blueprint::components::TimelineName; +pub use re_types::blueprint::components::UiRadius; pub use re_types::blueprint::components::ViewFit; pub use re_types::blueprint::components::ViewerRecommendationHash; pub use re_types::blueprint::components::Visible; @@ -51,11 +54,13 @@ pub fn is_valid_blueprint(blueprint: &EntityDb) -> bool { && validate_component::(blueprint) && validate_component::(blueprint) && validate_component::(blueprint) + && validate_component::(blueprint) && validate_component::(blueprint) && validate_component::(blueprint) && validate_component::(blueprint) && validate_component::(blueprint) && validate_component::(blueprint) + && validate_component::(blueprint) && validate_component::(blueprint) && validate_component::(blueprint) && validate_component::(blueprint) @@ -65,6 +70,7 @@ pub fn is_valid_blueprint(blueprint: &EntityDb) -> bool { && validate_component::(blueprint) && validate_component::(blueprint) && validate_component::(blueprint) + && validate_component::(blueprint) && validate_component::(blueprint) && validate_component::(blueprint) && validate_component::(blueprint) diff --git a/crates/viewer/re_viewer/src/reflection/mod.rs b/crates/viewer/re_viewer/src/reflection/mod.rs index 21424df3e255..ce58c04cd6c0 100644 --- a/crates/viewer/re_viewer/src/reflection/mod.rs +++ b/crates/viewer/re_viewer/src/reflection/mod.rs @@ -132,6 +132,14 @@ fn generate_component_reflection() -> Result::name(), + ComponentReflection { + docstring_md: "Space between grid lines of one line to the next in scene units.", + custom_placeholder: Some(GridSpacing::default().to_arrow2()?), + datatype: GridSpacing::arrow2_datatype(), + }, + ), ( ::name(), ComponentReflection { @@ -172,6 +180,14 @@ fn generate_component_reflection() -> Result::name(), + ComponentReflection { + docstring_md: "Orientation of a 3D axis aligned plane.", + custom_placeholder: Some(PlaneOrientation::default().to_arrow2()?), + datatype: PlaneOrientation::arrow2_datatype(), + }, + ), ( ::name(), ComponentReflection { @@ -246,6 +262,14 @@ fn generate_component_reflection() -> Result::name(), + ComponentReflection { + docstring_md: "Like `Radius`, but in always in ui units.", + custom_placeholder: Some(UiRadius::default().to_arrow2()?), + datatype: UiRadius::arrow2_datatype(), + }, + ), ( ::name(), ComponentReflection { @@ -1930,6 +1954,36 @@ fn generate_archetype_reflection() -> ArchetypeReflectionMap { ], }, ), + ( + ArchetypeName::new("rerun.blueprint.archetypes.LineGrid3D"), + ArchetypeReflection { + display_name: "Line grid 3D", + view_types: &[], + fields: vec![ + ArchetypeFieldReflection { component_name : + "rerun.blueprint.components.Visible".into(), display_name : + "Visible", docstring_md : + "Whether the grid is visible.\n\nDefaults to true.", is_required : + false, }, ArchetypeFieldReflection { component_name : + "rerun.blueprint.components.GridSpacing".into(), display_name : + "Spacing", docstring_md : + "Space between grid lines spacing of one line to the next in scene units.", + is_required : false, }, ArchetypeFieldReflection { component_name : + "rerun.blueprint.components.UiRadius".into(), display_name : + "Line radius", docstring_md : + "How thick the lines should be in ui units.\n\nDefault is 0.5 ui unit.", + is_required : false, }, ArchetypeFieldReflection { component_name : + "rerun.components.Color".into(), display_name : "Color", docstring_md + : + "Color used for the grid.\n\nTransparency via alpha channel is supported.\nDefaults to a slightly transparent light gray.", + is_required : false, }, ArchetypeFieldReflection { component_name : + "rerun.blueprint.components.PlaneOrientation".into(), display_name : + "Orientation", docstring_md : + "How the grid is oriented.\n\nDefaults to whatever plane is determined as the down plane by view coordinates if present.", + is_required : false, }, + ], + }, + ), ( ArchetypeName::new("rerun.blueprint.archetypes.MapBackground"), ArchetypeReflection { diff --git a/rerun_cpp/src/rerun/blueprint/archetypes.hpp b/rerun_cpp/src/rerun/blueprint/archetypes.hpp index 2fd779424b1f..09042a682126 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes.hpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes.hpp @@ -5,6 +5,7 @@ #include "blueprint/archetypes/background.hpp" #include "blueprint/archetypes/container_blueprint.hpp" #include "blueprint/archetypes/dataframe_query.hpp" +#include "blueprint/archetypes/line_grid3d.hpp" #include "blueprint/archetypes/map_background.hpp" #include "blueprint/archetypes/map_zoom.hpp" #include "blueprint/archetypes/panel_blueprint.hpp" diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/.gitattributes b/rerun_cpp/src/rerun/blueprint/archetypes/.gitattributes index 26e1a60b89a6..ec736e25d263 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/.gitattributes +++ b/rerun_cpp/src/rerun/blueprint/archetypes/.gitattributes @@ -7,6 +7,8 @@ container_blueprint.cpp linguist-generated=true container_blueprint.hpp linguist-generated=true dataframe_query.cpp linguist-generated=true dataframe_query.hpp linguist-generated=true +line_grid3d.cpp linguist-generated=true +line_grid3d.hpp linguist-generated=true map_background.cpp linguist-generated=true map_background.hpp linguist-generated=true map_zoom.cpp linguist-generated=true diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.cpp b/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.cpp new file mode 100644 index 000000000000..b7d5e2a8d457 --- /dev/null +++ b/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.cpp @@ -0,0 +1,53 @@ +// 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/blueprint/archetypes/line_grid_3d.fbs". + +#include "line_grid3d.hpp" + +#include "../../collection_adapter_builtins.hpp" + +namespace rerun::blueprint::archetypes {} + +namespace rerun { + + Result> AsComponents::serialize( + const blueprint::archetypes::LineGrid3D& archetype + ) { + using namespace blueprint::archetypes; + std::vector cells; + cells.reserve(6); + + if (archetype.visible.has_value()) { + auto result = ComponentBatch::from_loggable(archetype.visible.value()); + RR_RETURN_NOT_OK(result.error); + cells.push_back(std::move(result.value)); + } + if (archetype.spacing.has_value()) { + auto result = ComponentBatch::from_loggable(archetype.spacing.value()); + RR_RETURN_NOT_OK(result.error); + cells.push_back(std::move(result.value)); + } + if (archetype.line_radius.has_value()) { + auto result = ComponentBatch::from_loggable(archetype.line_radius.value()); + RR_RETURN_NOT_OK(result.error); + cells.push_back(std::move(result.value)); + } + if (archetype.color.has_value()) { + auto result = ComponentBatch::from_loggable(archetype.color.value()); + RR_RETURN_NOT_OK(result.error); + cells.push_back(std::move(result.value)); + } + if (archetype.orientation.has_value()) { + auto result = ComponentBatch::from_loggable(archetype.orientation.value()); + RR_RETURN_NOT_OK(result.error); + cells.push_back(std::move(result.value)); + } + { + auto indicator = LineGrid3D::IndicatorComponent(); + auto result = ComponentBatch::from_loggable(indicator); + RR_RETURN_NOT_OK(result.error); + cells.emplace_back(std::move(result.value)); + } + + return cells; + } +} // namespace rerun diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.hpp b/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.hpp new file mode 100644 index 000000000000..0898bede41ad --- /dev/null +++ b/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.hpp @@ -0,0 +1,121 @@ +// 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/blueprint/archetypes/line_grid_3d.fbs". + +#pragma once + +#include "../../blueprint/components/grid_spacing.hpp" +#include "../../blueprint/components/plane_orientation.hpp" +#include "../../blueprint/components/ui_radius.hpp" +#include "../../blueprint/components/visible.hpp" +#include "../../collection.hpp" +#include "../../compiler_utils.hpp" +#include "../../component_batch.hpp" +#include "../../components/color.hpp" +#include "../../indicator_component.hpp" +#include "../../result.hpp" + +#include +#include +#include +#include + +namespace rerun::blueprint::archetypes { + /// **Archetype**: Configuration for the 3D line grid. + struct LineGrid3D { + /// Whether the grid is visible. + /// + /// Defaults to true. + std::optional visible; + + /// Space between grid lines spacing of one line to the next in scene units. + std::optional spacing; + + /// How thick the lines should be in ui units. + /// + /// Default is 0.5 ui unit. + std::optional line_radius; + + /// Color used for the grid. + /// + /// Transparency via alpha channel is supported. + /// Defaults to a slightly transparent light gray. + std::optional color; + + /// How the grid is oriented. + /// + /// Defaults to whatever plane is determined as the down plane by view coordinates if present. + std::optional orientation; + + public: + static constexpr const char IndicatorComponentName[] = + "rerun.blueprint.components.LineGrid3DIndicator"; + + /// Indicator component, used to identify the archetype when converting to a list of components. + using IndicatorComponent = rerun::components::IndicatorComponent; + + public: + LineGrid3D() = default; + LineGrid3D(LineGrid3D&& other) = default; + + /// Whether the grid is visible. + /// + /// Defaults to true. + LineGrid3D with_visible(rerun::blueprint::components::Visible _visible) && { + visible = std::move(_visible); + // See: https://github.com/rerun-io/rerun/issues/4027 + RR_WITH_MAYBE_UNINITIALIZED_DISABLED(return std::move(*this);) + } + + /// Space between grid lines spacing of one line to the next in scene units. + LineGrid3D with_spacing(rerun::blueprint::components::GridSpacing _spacing) && { + spacing = std::move(_spacing); + // See: https://github.com/rerun-io/rerun/issues/4027 + RR_WITH_MAYBE_UNINITIALIZED_DISABLED(return std::move(*this);) + } + + /// How thick the lines should be in ui units. + /// + /// Default is 0.5 ui unit. + LineGrid3D with_line_radius(rerun::blueprint::components::UiRadius _line_radius) && { + line_radius = std::move(_line_radius); + // See: https://github.com/rerun-io/rerun/issues/4027 + RR_WITH_MAYBE_UNINITIALIZED_DISABLED(return std::move(*this);) + } + + /// Color used for the grid. + /// + /// Transparency via alpha channel is supported. + /// Defaults to a slightly transparent light gray. + LineGrid3D with_color(rerun::components::Color _color) && { + color = std::move(_color); + // See: https://github.com/rerun-io/rerun/issues/4027 + RR_WITH_MAYBE_UNINITIALIZED_DISABLED(return std::move(*this);) + } + + /// How the grid is oriented. + /// + /// Defaults to whatever plane is determined as the down plane by view coordinates if present. + LineGrid3D with_orientation(rerun::blueprint::components::PlaneOrientation _orientation + ) && { + orientation = std::move(_orientation); + // See: https://github.com/rerun-io/rerun/issues/4027 + RR_WITH_MAYBE_UNINITIALIZED_DISABLED(return std::move(*this);) + } + }; + +} // namespace rerun::blueprint::archetypes + +namespace rerun { + /// \private + template + struct AsComponents; + + /// \private + template <> + struct AsComponents { + /// Serialize all set component batches. + static Result> serialize( + const blueprint::archetypes::LineGrid3D& archetype + ); + }; +} // namespace rerun diff --git a/rerun_cpp/src/rerun/blueprint/components.hpp b/rerun_cpp/src/rerun/blueprint/components.hpp index e426e3a2b486..0bd8e4a7887f 100644 --- a/rerun_cpp/src/rerun/blueprint/components.hpp +++ b/rerun_cpp/src/rerun/blueprint/components.hpp @@ -14,11 +14,13 @@ #include "blueprint/components/filter_by_range.hpp" #include "blueprint/components/filter_is_not_null.hpp" #include "blueprint/components/grid_columns.hpp" +#include "blueprint/components/grid_spacing.hpp" #include "blueprint/components/included_content.hpp" #include "blueprint/components/interactive.hpp" #include "blueprint/components/lock_range_during_zoom.hpp" #include "blueprint/components/map_provider.hpp" #include "blueprint/components/panel_state.hpp" +#include "blueprint/components/plane_orientation.hpp" #include "blueprint/components/query_expression.hpp" #include "blueprint/components/root_container.hpp" #include "blueprint/components/row_share.hpp" @@ -28,6 +30,7 @@ #include "blueprint/components/space_view_origin.hpp" #include "blueprint/components/tensor_dimension_index_slider.hpp" #include "blueprint/components/timeline_name.hpp" +#include "blueprint/components/ui_radius.hpp" #include "blueprint/components/view_fit.hpp" #include "blueprint/components/viewer_recommendation_hash.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 7b2410956aec..1ef9d20500bb 100644 --- a/rerun_cpp/src/rerun/blueprint/components/.gitattributes +++ b/rerun_cpp/src/rerun/blueprint/components/.gitattributes @@ -16,6 +16,7 @@ corner2d.hpp linguist-generated=true filter_by_range.hpp linguist-generated=true filter_is_not_null.hpp linguist-generated=true grid_columns.hpp linguist-generated=true +grid_spacing.hpp linguist-generated=true included_content.hpp linguist-generated=true interactive.hpp linguist-generated=true lock_range_during_zoom.hpp linguist-generated=true @@ -23,6 +24,8 @@ map_provider.cpp linguist-generated=true map_provider.hpp linguist-generated=true panel_state.cpp linguist-generated=true panel_state.hpp linguist-generated=true +plane_orientation.cpp linguist-generated=true +plane_orientation.hpp linguist-generated=true query_expression.hpp linguist-generated=true root_container.hpp linguist-generated=true row_share.hpp linguist-generated=true @@ -32,6 +35,7 @@ space_view_maximized.hpp linguist-generated=true space_view_origin.hpp linguist-generated=true tensor_dimension_index_slider.hpp linguist-generated=true timeline_name.hpp linguist-generated=true +ui_radius.hpp linguist-generated=true view_fit.cpp linguist-generated=true view_fit.hpp linguist-generated=true viewer_recommendation_hash.hpp linguist-generated=true diff --git a/rerun_cpp/src/rerun/blueprint/components/grid_spacing.hpp b/rerun_cpp/src/rerun/blueprint/components/grid_spacing.hpp new file mode 100644 index 000000000000..7cd2209a30f3 --- /dev/null +++ b/rerun_cpp/src/rerun/blueprint/components/grid_spacing.hpp @@ -0,0 +1,74 @@ +// 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/blueprint/components/grid_spacing.fbs". + +#pragma once + +#include "../../datatypes/float32.hpp" +#include "../../result.hpp" + +#include +#include + +namespace rerun::blueprint::components { + /// **Component**: Space between grid lines of one line to the next in scene units. + struct GridSpacing { + /// Space between grid lines of one line to the next in scene units. + rerun::datatypes::Float32 distance; + + public: + GridSpacing() = default; + + GridSpacing(rerun::datatypes::Float32 distance_) : distance(distance_) {} + + GridSpacing& operator=(rerun::datatypes::Float32 distance_) { + distance = distance_; + return *this; + } + + GridSpacing(float value_) : distance(value_) {} + + GridSpacing& operator=(float value_) { + distance = value_; + return *this; + } + + /// Cast to the underlying Float32 datatype + operator rerun::datatypes::Float32() const { + return distance; + } + }; +} // namespace rerun::blueprint::components + +namespace rerun { + static_assert(sizeof(rerun::datatypes::Float32) == sizeof(blueprint::components::GridSpacing)); + + /// \private + template <> + struct Loggable { + static constexpr const char Name[] = "rerun.blueprint.components.GridSpacing"; + + /// Returns the arrow data type this type corresponds to. + static const std::shared_ptr& arrow_datatype() { + return Loggable::arrow_datatype(); + } + + /// Serializes an array of `rerun::blueprint:: components::GridSpacing` into an arrow array. + static Result> to_arrow( + const blueprint::components::GridSpacing* instances, size_t num_instances + ) { + if (num_instances == 0) { + return Loggable::to_arrow(nullptr, 0); + } else if (instances == nullptr) { + return rerun::Error( + ErrorCode::UnexpectedNullArgument, + "Passed array instances is null when num_elements> 0." + ); + } else { + return Loggable::to_arrow( + &instances->distance, + num_instances + ); + } + } + }; +} // namespace rerun diff --git a/rerun_cpp/src/rerun/blueprint/components/plane_orientation.cpp b/rerun_cpp/src/rerun/blueprint/components/plane_orientation.cpp new file mode 100644 index 000000000000..5fce189de63c --- /dev/null +++ b/rerun_cpp/src/rerun/blueprint/components/plane_orientation.cpp @@ -0,0 +1,61 @@ +// 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/blueprint/components/plane_orientation.fbs". + +#include "plane_orientation.hpp" + +#include +#include + +namespace rerun { + const std::shared_ptr& + Loggable::arrow_datatype() { + static const auto datatype = arrow::uint8(); + return datatype; + } + + Result> + Loggable::to_arrow( + const blueprint::components::PlaneOrientation* 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::UInt8Builder* builder, const blueprint::components::PlaneOrientation* 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." + ); + } + + ARROW_RETURN_NOT_OK(builder->Reserve(static_cast(num_elements))); + for (size_t elem_idx = 0; elem_idx < num_elements; elem_idx += 1) { + const auto variant = elements[elem_idx]; + ARROW_RETURN_NOT_OK(builder->Append(static_cast(variant))); + } + + return Error::ok(); + } +} // namespace rerun diff --git a/rerun_cpp/src/rerun/blueprint/components/plane_orientation.hpp b/rerun_cpp/src/rerun/blueprint/components/plane_orientation.hpp new file mode 100644 index 000000000000..3ee04df0bfea --- /dev/null +++ b/rerun_cpp/src/rerun/blueprint/components/plane_orientation.hpp @@ -0,0 +1,60 @@ +// 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/blueprint/components/plane_orientation.fbs". + +#pragma once + +#include "../../result.hpp" + +#include +#include + +namespace arrow { + /// \private + template + class NumericBuilder; + + class Array; + class DataType; + class UInt8Type; + using UInt8Builder = NumericBuilder; +} // namespace arrow + +namespace rerun::blueprint::components { + /// **Component**: Orientation of a 3D axis aligned plane. + enum class PlaneOrientation : uint8_t { + + /// Plane spanned by X and Z axis. + Xz = 1, + + /// Plane spanned by Y and Z axis. + Yz = 2, + + /// Plane spanned by X and Y axis. + Xy = 3, + }; +} // namespace rerun::blueprint::components + +namespace rerun { + template + struct Loggable; + + /// \private + template <> + struct Loggable { + static constexpr const char Name[] = "rerun.blueprint.components.PlaneOrientation"; + + /// Returns the arrow data type this type corresponds to. + static const std::shared_ptr& arrow_datatype(); + + /// Serializes an array of `rerun::blueprint:: components::PlaneOrientation` into an arrow array. + static Result> to_arrow( + const blueprint::components::PlaneOrientation* instances, size_t num_instances + ); + + /// Fills an arrow array builder with an array of this type. + static rerun::Error fill_arrow_array_builder( + arrow::UInt8Builder* builder, const blueprint::components::PlaneOrientation* elements, + size_t num_elements + ); + }; +} // namespace rerun diff --git a/rerun_cpp/src/rerun/blueprint/components/ui_radius.hpp b/rerun_cpp/src/rerun/blueprint/components/ui_radius.hpp new file mode 100644 index 000000000000..5141e3f871f8 --- /dev/null +++ b/rerun_cpp/src/rerun/blueprint/components/ui_radius.hpp @@ -0,0 +1,74 @@ +// 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/blueprint/components/ui_radius.fbs". + +#pragma once + +#include "../../datatypes/float32.hpp" +#include "../../result.hpp" + +#include +#include + +namespace rerun::blueprint::components { + /// **Component**: Like `Radius`, but in always in ui units. + struct UiRadius { + /// Radius in ui units. + rerun::datatypes::Float32 radius; + + public: + UiRadius() = default; + + UiRadius(rerun::datatypes::Float32 radius_) : radius(radius_) {} + + UiRadius& operator=(rerun::datatypes::Float32 radius_) { + radius = radius_; + return *this; + } + + UiRadius(float value_) : radius(value_) {} + + UiRadius& operator=(float value_) { + radius = value_; + return *this; + } + + /// Cast to the underlying Float32 datatype + operator rerun::datatypes::Float32() const { + return radius; + } + }; +} // namespace rerun::blueprint::components + +namespace rerun { + static_assert(sizeof(rerun::datatypes::Float32) == sizeof(blueprint::components::UiRadius)); + + /// \private + template <> + struct Loggable { + static constexpr const char Name[] = "rerun.blueprint.components.UiRadius"; + + /// Returns the arrow data type this type corresponds to. + static const std::shared_ptr& arrow_datatype() { + return Loggable::arrow_datatype(); + } + + /// Serializes an array of `rerun::blueprint:: components::UiRadius` into an arrow array. + static Result> to_arrow( + const blueprint::components::UiRadius* instances, size_t num_instances + ) { + if (num_instances == 0) { + return Loggable::to_arrow(nullptr, 0); + } else if (instances == nullptr) { + return rerun::Error( + ErrorCode::UnexpectedNullArgument, + "Passed array instances is null when num_elements> 0." + ); + } else { + return Loggable::to_arrow( + &instances->radius, + num_instances + ); + } + } + }; +} // namespace rerun diff --git a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/.gitattributes b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/.gitattributes index bb528bfbaf9a..45d2c2e0e797 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/.gitattributes +++ b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/.gitattributes @@ -5,6 +5,7 @@ __init__.py linguist-generated=true background.py linguist-generated=true container_blueprint.py linguist-generated=true dataframe_query.py linguist-generated=true +line_grid3d.py linguist-generated=true map_background.py linguist-generated=true map_zoom.py linguist-generated=true panel_blueprint.py linguist-generated=true diff --git a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/__init__.py b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/__init__.py index 018ec6c34d5e..de30db55093f 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/__init__.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/__init__.py @@ -5,6 +5,7 @@ from .background import Background from .container_blueprint import ContainerBlueprint from .dataframe_query import DataframeQuery +from .line_grid3d import LineGrid3D from .map_background import MapBackground from .map_zoom import MapZoom from .panel_blueprint import PanelBlueprint @@ -23,6 +24,7 @@ "Background", "ContainerBlueprint", "DataframeQuery", + "LineGrid3D", "MapBackground", "MapZoom", "PanelBlueprint", diff --git a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/line_grid3d.py b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/line_grid3d.py new file mode 100644 index 000000000000..b97765275e2b --- /dev/null +++ b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/line_grid3d.py @@ -0,0 +1,142 @@ +# 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/blueprint/archetypes/line_grid_3d.fbs". + +# You can extend this class by creating a "LineGrid3DExt" class in "line_grid3d_ext.py". + +from __future__ import annotations + +from typing import Any + +from attrs import define, field + +from ... import components, datatypes +from ..._baseclasses import ( + Archetype, +) +from ...blueprint import components as blueprint_components +from ...error_utils import catch_and_log_exceptions + +__all__ = ["LineGrid3D"] + + +@define(str=False, repr=False, init=False) +class LineGrid3D(Archetype): + """**Archetype**: Configuration for the 3D line grid.""" + + def __init__( + self: Any, + *, + visible: datatypes.BoolLike | None = None, + spacing: datatypes.Float32Like | None = None, + line_radius: datatypes.Float32Like | None = None, + color: datatypes.Rgba32Like | None = None, + orientation: blueprint_components.PlaneOrientationLike | None = None, + ): + """ + Create a new instance of the LineGrid3D archetype. + + Parameters + ---------- + visible: + Whether the grid is visible. + + Defaults to true. + spacing: + Space between grid lines spacing of one line to the next in scene units. + line_radius: + How thick the lines should be in ui units. + + Default is 0.5 ui unit. + color: + Color used for the grid. + + Transparency via alpha channel is supported. + Defaults to a slightly transparent light gray. + orientation: + How the grid is oriented. + + Defaults to whatever plane is determined as the down plane by view coordinates if present. + + """ + + # You can define your own __init__ function as a member of LineGrid3DExt in line_grid3d_ext.py + with catch_and_log_exceptions(context=self.__class__.__name__): + self.__attrs_init__( + visible=visible, spacing=spacing, line_radius=line_radius, color=color, orientation=orientation + ) + return + self.__attrs_clear__() + + def __attrs_clear__(self) -> None: + """Convenience method for calling `__attrs_init__` with all `None`s.""" + self.__attrs_init__( + visible=None, # type: ignore[arg-type] + spacing=None, # type: ignore[arg-type] + line_radius=None, # type: ignore[arg-type] + color=None, # type: ignore[arg-type] + orientation=None, # type: ignore[arg-type] + ) + + @classmethod + def _clear(cls) -> LineGrid3D: + """Produce an empty LineGrid3D, bypassing `__init__`.""" + inst = cls.__new__(cls) + inst.__attrs_clear__() + return inst + + visible: blueprint_components.VisibleBatch | None = field( + metadata={"component": "optional"}, + default=None, + converter=blueprint_components.VisibleBatch._optional, # type: ignore[misc] + ) + # Whether the grid is visible. + # + # Defaults to true. + # + # (Docstring intentionally commented out to hide this field from the docs) + + spacing: blueprint_components.GridSpacingBatch | None = field( + metadata={"component": "optional"}, + default=None, + converter=blueprint_components.GridSpacingBatch._optional, # type: ignore[misc] + ) + # Space between grid lines spacing of one line to the next in scene units. + # + # (Docstring intentionally commented out to hide this field from the docs) + + line_radius: blueprint_components.UiRadiusBatch | None = field( + metadata={"component": "optional"}, + default=None, + converter=blueprint_components.UiRadiusBatch._optional, # type: ignore[misc] + ) + # How thick the lines should be in ui units. + # + # Default is 0.5 ui unit. + # + # (Docstring intentionally commented out to hide this field from the docs) + + color: components.ColorBatch | None = field( + metadata={"component": "optional"}, + default=None, + converter=components.ColorBatch._optional, # type: ignore[misc] + ) + # Color used for the grid. + # + # Transparency via alpha channel is supported. + # Defaults to a slightly transparent light gray. + # + # (Docstring intentionally commented out to hide this field from the docs) + + orientation: blueprint_components.PlaneOrientationBatch | None = field( + metadata={"component": "optional"}, + default=None, + converter=blueprint_components.PlaneOrientationBatch._optional, # type: ignore[misc] + ) + # How the grid is oriented. + # + # Defaults to whatever plane is determined as the down plane by view coordinates if present. + # + # (Docstring intentionally commented out to hide this field from the docs) + + __str__ = Archetype.__str__ + __repr__ = Archetype.__repr__ # type: ignore[assignment] diff --git a/rerun_py/rerun_sdk/rerun/blueprint/components/.gitattributes b/rerun_py/rerun_sdk/rerun/blueprint/components/.gitattributes index 57164211651c..b6873b65b5f7 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/components/.gitattributes +++ b/rerun_py/rerun_sdk/rerun/blueprint/components/.gitattributes @@ -14,11 +14,13 @@ corner2d.py linguist-generated=true filter_by_range.py linguist-generated=true filter_is_not_null.py linguist-generated=true grid_columns.py linguist-generated=true +grid_spacing.py linguist-generated=true included_content.py linguist-generated=true interactive.py linguist-generated=true lock_range_during_zoom.py linguist-generated=true map_provider.py linguist-generated=true panel_state.py linguist-generated=true +plane_orientation.py linguist-generated=true query_expression.py linguist-generated=true root_container.py linguist-generated=true row_share.py linguist-generated=true @@ -28,6 +30,7 @@ space_view_maximized.py linguist-generated=true space_view_origin.py linguist-generated=true tensor_dimension_index_slider.py linguist-generated=true timeline_name.py linguist-generated=true +ui_radius.py linguist-generated=true view_fit.py linguist-generated=true viewer_recommendation_hash.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 2f4943b58c8d..31f2ccd28d38 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/components/__init__.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/components/__init__.py @@ -14,11 +14,13 @@ from .filter_by_range import FilterByRange, FilterByRangeBatch from .filter_is_not_null import FilterIsNotNull, FilterIsNotNullBatch from .grid_columns import GridColumns, GridColumnsBatch +from .grid_spacing import GridSpacing, GridSpacingBatch from .included_content import IncludedContent, IncludedContentBatch from .interactive import Interactive, InteractiveBatch from .lock_range_during_zoom import LockRangeDuringZoom, LockRangeDuringZoomBatch from .map_provider import MapProvider, MapProviderArrayLike, MapProviderBatch, MapProviderLike from .panel_state import PanelState, PanelStateArrayLike, PanelStateBatch, PanelStateLike +from .plane_orientation import PlaneOrientation, PlaneOrientationArrayLike, PlaneOrientationBatch, PlaneOrientationLike from .query_expression import QueryExpression, QueryExpressionBatch from .root_container import RootContainer, RootContainerBatch from .row_share import RowShare, RowShareBatch @@ -28,6 +30,7 @@ from .space_view_origin import SpaceViewOrigin, SpaceViewOriginBatch from .tensor_dimension_index_slider import TensorDimensionIndexSlider, TensorDimensionIndexSliderBatch from .timeline_name import TimelineName, TimelineNameBatch +from .ui_radius import UiRadius, UiRadiusBatch from .view_fit import ViewFit, ViewFitArrayLike, ViewFitBatch, ViewFitLike from .viewer_recommendation_hash import ViewerRecommendationHash, ViewerRecommendationHashBatch from .visible import Visible, VisibleBatch @@ -67,6 +70,8 @@ "FilterIsNotNullBatch", "GridColumns", "GridColumnsBatch", + "GridSpacing", + "GridSpacingBatch", "IncludedContent", "IncludedContentBatch", "Interactive", @@ -81,6 +86,10 @@ "PanelStateArrayLike", "PanelStateBatch", "PanelStateLike", + "PlaneOrientation", + "PlaneOrientationArrayLike", + "PlaneOrientationBatch", + "PlaneOrientationLike", "QueryExpression", "QueryExpressionBatch", "RootContainer", @@ -99,6 +108,8 @@ "TensorDimensionIndexSliderBatch", "TimelineName", "TimelineNameBatch", + "UiRadius", + "UiRadiusBatch", "ViewFit", "ViewFitArrayLike", "ViewFitBatch", diff --git a/rerun_py/rerun_sdk/rerun/blueprint/components/grid_spacing.py b/rerun_py/rerun_sdk/rerun/blueprint/components/grid_spacing.py new file mode 100644 index 000000000000..7b5c98387176 --- /dev/null +++ b/rerun_py/rerun_sdk/rerun/blueprint/components/grid_spacing.py @@ -0,0 +1,32 @@ +# 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/blueprint/components/grid_spacing.fbs". + +# You can extend this class by creating a "GridSpacingExt" class in "grid_spacing_ext.py". + +from __future__ import annotations + +from ... import datatypes +from ..._baseclasses import ( + ComponentBatchMixin, + ComponentMixin, +) + +__all__ = ["GridSpacing", "GridSpacingBatch"] + + +class GridSpacing(datatypes.Float32, ComponentMixin): + """**Component**: Space between grid lines of one line to the next in scene units.""" + + _BATCH_TYPE = None + # You can define your own __init__ function as a member of GridSpacingExt in grid_spacing_ext.py + + # Note: there are no fields here because GridSpacing delegates to datatypes.Float32 + pass + + +class GridSpacingBatch(datatypes.Float32Batch, ComponentBatchMixin): + _COMPONENT_NAME: str = "rerun.blueprint.components.GridSpacing" + + +# This is patched in late to avoid circular dependencies. +GridSpacing._BATCH_TYPE = GridSpacingBatch # type: ignore[assignment] diff --git a/rerun_py/rerun_sdk/rerun/blueprint/components/plane_orientation.py b/rerun_py/rerun_sdk/rerun/blueprint/components/plane_orientation.py new file mode 100644 index 000000000000..07ed958eaf2e --- /dev/null +++ b/rerun_py/rerun_sdk/rerun/blueprint/components/plane_orientation.py @@ -0,0 +1,71 @@ +# 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/blueprint/components/plane_orientation.fbs". + +# You can extend this class by creating a "PlaneOrientationExt" class in "plane_orientation_ext.py". + +from __future__ import annotations + +from typing import Literal, Sequence, Union + +import pyarrow as pa + +from ..._baseclasses import ( + BaseBatch, + ComponentBatchMixin, +) + +__all__ = ["PlaneOrientation", "PlaneOrientationArrayLike", "PlaneOrientationBatch", "PlaneOrientationLike"] + + +from enum import Enum + + +class PlaneOrientation(Enum): + """**Component**: Orientation of a 3D axis aligned plane.""" + + Xz = 1 + """Plane spanned by X and Z axis.""" + + Yz = 2 + """Plane spanned by Y and Z axis.""" + + Xy = 3 + """Plane spanned by X and Y axis.""" + + @classmethod + def auto(cls, val: str | int | PlaneOrientation) -> PlaneOrientation: + """Best-effort converter, including a case-insensitive string matcher.""" + if isinstance(val, PlaneOrientation): + return val + if isinstance(val, int): + return cls(val) + try: + return cls[val] + except KeyError: + val_lower = val.lower() + for variant in cls: + if variant.name.lower() == val_lower: + return variant + raise ValueError(f"Cannot convert {val} to {cls.__name__}") + + def __str__(self) -> str: + """Returns the variant name.""" + return self.name + + +PlaneOrientationLike = Union[PlaneOrientation, Literal["Xy", "Xz", "Yz", "xy", "xz", "yz"], int] +PlaneOrientationArrayLike = Union[PlaneOrientationLike, Sequence[PlaneOrientationLike]] + + +class PlaneOrientationBatch(BaseBatch[PlaneOrientationArrayLike], ComponentBatchMixin): + _ARROW_DATATYPE = pa.uint8() + _COMPONENT_NAME: str = "rerun.blueprint.components.PlaneOrientation" + + @staticmethod + def _native_to_pa_array(data: PlaneOrientationArrayLike, data_type: pa.DataType) -> pa.Array: + if isinstance(data, (PlaneOrientation, int, str)): + data = [data] + + pa_data = [PlaneOrientation.auto(v).value if v is not None else None for v in data] # type: ignore[redundant-expr] + + return pa.array(pa_data, type=data_type) diff --git a/rerun_py/rerun_sdk/rerun/blueprint/components/ui_radius.py b/rerun_py/rerun_sdk/rerun/blueprint/components/ui_radius.py new file mode 100644 index 000000000000..322572fe21f5 --- /dev/null +++ b/rerun_py/rerun_sdk/rerun/blueprint/components/ui_radius.py @@ -0,0 +1,32 @@ +# 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/blueprint/components/ui_radius.fbs". + +# You can extend this class by creating a "UiRadiusExt" class in "ui_radius_ext.py". + +from __future__ import annotations + +from ... import datatypes +from ..._baseclasses import ( + ComponentBatchMixin, + ComponentMixin, +) + +__all__ = ["UiRadius", "UiRadiusBatch"] + + +class UiRadius(datatypes.Float32, ComponentMixin): + """**Component**: Like `Radius`, but in always in ui units.""" + + _BATCH_TYPE = None + # You can define your own __init__ function as a member of UiRadiusExt in ui_radius_ext.py + + # Note: there are no fields here because UiRadius delegates to datatypes.Float32 + pass + + +class UiRadiusBatch(datatypes.Float32Batch, ComponentBatchMixin): + _COMPONENT_NAME: str = "rerun.blueprint.components.UiRadius" + + +# This is patched in late to avoid circular dependencies. +UiRadius._BATCH_TYPE = UiRadiusBatch # type: ignore[assignment] From 9eb7b3785c30fd8e81d218f266669c625c80fffa Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Wed, 27 Nov 2024 14:46:26 +0100 Subject: [PATCH 02/29] add line grid to spatial3d definition --- .../definitions/rerun/blueprint/views/spatial3d.fbs | 3 +++ .../store/re_types/src/blueprint/views/spatial3d_view.rs | 8 +++++++- docs/content/reference/types/views/spatial3d_view.md | 8 ++++++++ .../rerun_sdk/rerun/blueprint/views/spatial3d_view.py | 8 ++++++++ 4 files changed, 26 insertions(+), 1 deletion(-) diff --git a/crates/store/re_types/definitions/rerun/blueprint/views/spatial3d.fbs b/crates/store/re_types/definitions/rerun/blueprint/views/spatial3d.fbs index 53d18994433b..ba69f61302cc 100644 --- a/crates/store/re_types/definitions/rerun/blueprint/views/spatial3d.fbs +++ b/crates/store/re_types/definitions/rerun/blueprint/views/spatial3d.fbs @@ -9,6 +9,9 @@ table Spatial3DView ( /// Configuration for the background of the view. background: rerun.blueprint.archetypes.Background (order: 1000); + /// Configuration for the 3D line grid. + line_grid: rerun.blueprint.archetypes.LineGrid3D (order: 2000); + /// Configures which range on each timeline is shown by this view (unless specified differently per entity). /// /// If not specified, the default is to show the latest state of each component. diff --git a/crates/store/re_types/src/blueprint/views/spatial3d_view.rs b/crates/store/re_types/src/blueprint/views/spatial3d_view.rs index 7eb491d3334f..2c1987c0c473 100644 --- a/crates/store/re_types/src/blueprint/views/spatial3d_view.rs +++ b/crates/store/re_types/src/blueprint/views/spatial3d_view.rs @@ -24,6 +24,9 @@ pub struct Spatial3DView { /// Configuration for the background of the view. pub background: crate::blueprint::archetypes::Background, + /// Configuration for the 3D line grid. + pub line_grid: crate::blueprint::archetypes::LineGrid3D, + /// Configures which range on each timeline is shown by this view (unless specified differently per entity). /// /// If not specified, the default is to show the latest state of each component. @@ -34,12 +37,15 @@ pub struct Spatial3DView { impl ::re_types_core::SizeBytes for Spatial3DView { #[inline] fn heap_size_bytes(&self) -> u64 { - self.background.heap_size_bytes() + self.time_ranges.heap_size_bytes() + self.background.heap_size_bytes() + + self.line_grid.heap_size_bytes() + + self.time_ranges.heap_size_bytes() } #[inline] fn is_pod() -> bool { ::is_pod() + && ::is_pod() && ::is_pod() } } diff --git a/docs/content/reference/types/views/spatial3d_view.md b/docs/content/reference/types/views/spatial3d_view.md index 95f5ecbb2068..5ff22ffa2e8c 100644 --- a/docs/content/reference/types/views/spatial3d_view.md +++ b/docs/content/reference/types/views/spatial3d_view.md @@ -12,6 +12,14 @@ Configuration for the background of the view. * `kind`: The type of the background. * `color`: Color used for the `SolidColor` background type. +### `line_grid` +Configuration for the 3D line grid. + +* `visible`: Whether the grid is visible. +* `spacing`: Space between grid lines spacing of one line to the next in scene units. +* `line_radius`: How thick the lines should be in ui units. +* `color`: Color used for the grid. +* `orientation`: How the grid is oriented. ### `time_ranges` Configures which range on each timeline is shown by this view (unless specified differently per entity). diff --git a/rerun_py/rerun_sdk/rerun/blueprint/views/spatial3d_view.py b/rerun_py/rerun_sdk/rerun/blueprint/views/spatial3d_view.py index f2684b5493d1..a880cde684bd 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/views/spatial3d_view.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/views/spatial3d_view.py @@ -76,6 +76,7 @@ def __init__( | datatypes.Rgba32Like | blueprint_components.BackgroundKindLike | None = None, + line_grid: blueprint_archetypes.LineGrid3D | None = None, time_ranges: blueprint_archetypes.VisibleTimeRanges | datatypes.VisibleTimeRangeLike | Sequence[datatypes.VisibleTimeRangeLike] @@ -112,6 +113,8 @@ def __init__( This will be addressed in . background: Configuration for the background of the view. + line_grid: + Configuration for the 3D line grid. time_ranges: Configures which range on each timeline is shown by this view (unless specified differently per entity). @@ -126,6 +129,11 @@ def __init__( background = blueprint_archetypes.Background(background) properties["Background"] = background + if line_grid is not None: + if not isinstance(line_grid, blueprint_archetypes.LineGrid3D): + line_grid = blueprint_archetypes.LineGrid3D(line_grid) + properties["LineGrid3D"] = line_grid + if time_ranges is not None: if not isinstance(time_ranges, blueprint_archetypes.VisibleTimeRanges): time_ranges = blueprint_archetypes.VisibleTimeRanges(time_ranges) From 3338bb955ab6e638ee6c847b4ad732dddfd29b1a Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Wed, 27 Nov 2024 14:50:08 +0100 Subject: [PATCH 03/29] expose in ui --- crates/viewer/re_component_ui/src/lib.rs | 11 ++++++++--- crates/viewer/re_component_ui/src/zoom_level.rs | 6 +++--- crates/viewer/re_space_view_spatial/src/view_3d.rs | 2 ++ 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/crates/viewer/re_component_ui/src/lib.rs b/crates/viewer/re_component_ui/src/lib.rs index 9ee313c198b7..feb2b523b497 100644 --- a/crates/viewer/re_component_ui/src/lib.rs +++ b/crates/viewer/re_component_ui/src/lib.rs @@ -34,7 +34,8 @@ use datatype_uis::{ use re_types::{ blueprint::components::{ - BackgroundKind, Corner2D, LockRangeDuringZoom, MapProvider, ViewFit, Visible, ZoomLevel, + BackgroundKind, Corner2D, GridSpacing, LockRangeDuringZoom, MapProvider, PlaneOrientation, + UiRadius, ViewFit, Visible, }, components::{ AggregationPolicy, AlbedoFactor, AxisLength, Color, DepthMeter, DrawOrder, FillMode, @@ -71,10 +72,11 @@ pub fn create_component_ui_registry() -> re_viewer_context::ComponentUiRegistry registry.add_singleline_edit_or_view::(edit_f32_zero_to_max); registry.add_singleline_edit_or_view::(edit_f32_zero_to_max); registry.add_singleline_edit_or_view::(edit_f32_zero_to_max); + registry.add_singleline_edit_or_view::(edit_f32_zero_to_max); registry.add_singleline_edit_or_view::(edit_f32_zero_to_max); registry.add_singleline_edit_or_view::(edit_f32_zero_to_max); registry.add_singleline_edit_or_view::(edit_f32_zero_to_max); - registry.add_singleline_edit_or_view::(zoom_level::edit_zoom_level); + registry.add_singleline_edit_or_view::(edit_f32_zero_to_max); // float min-max components: registry.add_singleline_edit_or_view::(edit_f32_min_to_max_float); @@ -103,13 +105,14 @@ pub fn create_component_ui_registry() -> re_viewer_context::ComponentUiRegistry registry.add_singleline_edit_or_view::(edit_view_enum); registry.add_singleline_edit_or_view::(edit_view_enum); registry.add_singleline_edit_or_view::(edit_view_enum); - registry.add_singleline_edit_or_view::(edit_view_enum); + registry.add_singleline_edit_or_view::(edit_view_enum); registry.add_singleline_edit_or_view::( edit_view_enum_with_variant_available::< MapProvider, crate::map_provider::MapProviderVariantAvailable, >, ); + registry.add_singleline_edit_or_view::(edit_view_enum); registry.add_singleline_edit_or_view::(edit_view_enum); registry.add_singleline_edit_or_view::(edit_view_enum); @@ -167,5 +170,7 @@ pub fn create_component_ui_registry() -> re_viewer_context::ComponentUiRegistry registry.add_singleline_edit_or_view(lat_lon::singleline_view_lat_lon); + registry.add_singleline_edit_or_view(zoom_level::edit_zoom_level); + registry } diff --git a/crates/viewer/re_component_ui/src/zoom_level.rs b/crates/viewer/re_component_ui/src/zoom_level.rs index b03af554ea6d..0b086d46dd99 100644 --- a/crates/viewer/re_component_ui/src/zoom_level.rs +++ b/crates/viewer/re_component_ui/src/zoom_level.rs @@ -1,4 +1,4 @@ -use re_types::datatypes; +use re_types::blueprint::components::ZoomLevel; use re_viewer_context::MaybeMutRef; // TODO(#7876): move this to `re_space_view_map` when the crate is no longer behind a Cargo feature. @@ -11,11 +11,11 @@ const MAX_ZOOM_LEVEL: f64 = 19.0; pub fn edit_zoom_level( _ctx: &re_viewer_context::ViewerContext<'_>, ui: &mut egui::Ui, - value: &mut MaybeMutRef<'_, impl std::ops::DerefMut>, + value: &mut MaybeMutRef<'_, ZoomLevel>, ) -> egui::Response { let mut value: MaybeMutRef<'_, f64> = match value { MaybeMutRef::Ref(value) => MaybeMutRef::Ref(value), - MaybeMutRef::MutRef(value) => MaybeMutRef::MutRef(&mut value.deref_mut().0), + MaybeMutRef::MutRef(value) => MaybeMutRef::MutRef(&mut value.0), }; super::datatype_uis::edit_f64_float_raw_with_speed_impl( diff --git a/crates/viewer/re_space_view_spatial/src/view_3d.rs b/crates/viewer/re_space_view_spatial/src/view_3d.rs index f5a30cc85fd3..6ebb771a3b05 100644 --- a/crates/viewer/re_space_view_spatial/src/view_3d.rs +++ b/crates/viewer/re_space_view_spatial/src/view_3d.rs @@ -5,6 +5,7 @@ use nohash_hasher::IntSet; use re_entity_db::EntityDb; use re_log_types::EntityPath; use re_space_view::view_property_ui; +use re_types::blueprint::archetypes::LineGrid3D; use re_types::View; use re_types::{ blueprint::archetypes::Background, components::ViewCoordinates, Component, @@ -421,6 +422,7 @@ impl SpaceViewClass for SpatialSpaceView3D { re_ui::list_item::list_item_scope(ui, "spatial_view3d_selection_ui", |ui| { view_property_ui::(ctx, ui, view_id, self, state); + view_property_ui::(ctx, ui, view_id, self, state); }); Ok(()) From 0e85137d2ca8a728896c6b58cf0d6a7c32c5b45d Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Wed, 27 Nov 2024 15:10:01 +0100 Subject: [PATCH 04/29] fallbacks for new grid config values --- .../blueprint/components/grid_spacing.fbs | 3 +- .../rerun/blueprint/components/ui_radius.fbs | 3 +- .../src/blueprint/components/grid_spacing.rs | 2 +- .../blueprint/components/grid_spacing_ext.rs | 9 ++++ .../re_types/src/blueprint/components/mod.rs | 1 + .../src/blueprint/components/ui_radius.rs | 2 +- .../viewer/re_space_view_spatial/src/ui_3d.rs | 2 +- .../src/view_3d_properties.rs | 42 +++++++++++++++++-- crates/viewer/re_viewer/src/reflection/mod.rs | 2 +- 9 files changed, 54 insertions(+), 12 deletions(-) create mode 100644 crates/store/re_types/src/blueprint/components/grid_spacing_ext.rs diff --git a/crates/store/re_types/definitions/rerun/blueprint/components/grid_spacing.fbs b/crates/store/re_types/definitions/rerun/blueprint/components/grid_spacing.fbs index 47ee4e013035..79c680679c47 100644 --- a/crates/store/re_types/definitions/rerun/blueprint/components/grid_spacing.fbs +++ b/crates/store/re_types/definitions/rerun/blueprint/components/grid_spacing.fbs @@ -4,8 +4,7 @@ namespace rerun.blueprint.components; table GridSpacing ( "attr.python.aliases": "float", "attr.python.array_aliases": "npt.ArrayLike", - "attr.rerun.scope": "blueprint", - "attr.rust.derive": "Default" + "attr.rerun.scope": "blueprint" ) { /// Space between grid lines of one line to the next in scene units. distance: rerun.datatypes.Float32 (order: 100); diff --git a/crates/store/re_types/definitions/rerun/blueprint/components/ui_radius.fbs b/crates/store/re_types/definitions/rerun/blueprint/components/ui_radius.fbs index b511e3adb4d7..f2c977aca809 100644 --- a/crates/store/re_types/definitions/rerun/blueprint/components/ui_radius.fbs +++ b/crates/store/re_types/definitions/rerun/blueprint/components/ui_radius.fbs @@ -4,8 +4,7 @@ namespace rerun.blueprint.components; table UiRadius ( "attr.python.aliases": "float", "attr.python.array_aliases": "npt.ArrayLike", - "attr.rerun.scope": "blueprint", - "attr.rust.derive": "Default" + "attr.rerun.scope": "blueprint" ) { /// Radius in ui units. radius: rerun.datatypes.Float32 (order: 100); diff --git a/crates/store/re_types/src/blueprint/components/grid_spacing.rs b/crates/store/re_types/src/blueprint/components/grid_spacing.rs index 9b6784df7107..c729b3234385 100644 --- a/crates/store/re_types/src/blueprint/components/grid_spacing.rs +++ b/crates/store/re_types/src/blueprint/components/grid_spacing.rs @@ -19,7 +19,7 @@ use ::re_types_core::{ComponentBatch, MaybeOwnedComponentBatch}; use ::re_types_core::{DeserializationError, DeserializationResult}; /// **Component**: Space between grid lines of one line to the next in scene units. -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug)] pub struct GridSpacing( /// Space between grid lines of one line to the next in scene units. pub crate::datatypes::Float32, diff --git a/crates/store/re_types/src/blueprint/components/grid_spacing_ext.rs b/crates/store/re_types/src/blueprint/components/grid_spacing_ext.rs new file mode 100644 index 000000000000..75ff4c8e9974 --- /dev/null +++ b/crates/store/re_types/src/blueprint/components/grid_spacing_ext.rs @@ -0,0 +1,9 @@ +use super::GridSpacing; + +impl Default for GridSpacing { + #[inline] + fn default() -> Self { + // Default to a unit grid. + 1.0.into() + } +} diff --git a/crates/store/re_types/src/blueprint/components/mod.rs b/crates/store/re_types/src/blueprint/components/mod.rs index 67077e11411d..320a46e1001a 100644 --- a/crates/store/re_types/src/blueprint/components/mod.rs +++ b/crates/store/re_types/src/blueprint/components/mod.rs @@ -13,6 +13,7 @@ mod filter_by_range_ext; mod filter_is_not_null; mod filter_is_not_null_ext; mod grid_spacing; +mod grid_spacing_ext; mod included_content; mod interactive; mod interactive_ext; diff --git a/crates/store/re_types/src/blueprint/components/ui_radius.rs b/crates/store/re_types/src/blueprint/components/ui_radius.rs index 4b8dc6539ad1..a6b9ba7b9604 100644 --- a/crates/store/re_types/src/blueprint/components/ui_radius.rs +++ b/crates/store/re_types/src/blueprint/components/ui_radius.rs @@ -19,7 +19,7 @@ use ::re_types_core::{ComponentBatch, MaybeOwnedComponentBatch}; use ::re_types_core::{DeserializationError, DeserializationResult}; /// **Component**: Like `Radius`, but in always in ui units. -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug)] pub struct UiRadius( /// Radius in ui units. pub crate::datatypes::Float32, diff --git a/crates/viewer/re_space_view_spatial/src/ui_3d.rs b/crates/viewer/re_space_view_spatial/src/ui_3d.rs index 1a82a5794846..6141ae293402 100644 --- a/crates/viewer/re_space_view_spatial/src/ui_3d.rs +++ b/crates/viewer/re_space_view_spatial/src/ui_3d.rs @@ -54,7 +54,7 @@ pub struct View3DState { /// Last known view coordinates. /// Used to detect changes in view coordinates, in which case we reset the camera eye. - scene_view_coordinates: Option, + pub scene_view_coordinates: Option, // options: spin: bool, diff --git a/crates/viewer/re_space_view_spatial/src/view_3d_properties.rs b/crates/viewer/re_space_view_spatial/src/view_3d_properties.rs index 949fc00e1f65..a211ee3b64e4 100644 --- a/crates/viewer/re_space_view_spatial/src/view_3d_properties.rs +++ b/crates/viewer/re_space_view_spatial/src/view_3d_properties.rs @@ -1,17 +1,22 @@ use re_types::{ - blueprint::{archetypes::Background, components::BackgroundKind}, + blueprint::{ + archetypes::{Background, LineGrid3D}, + components::{BackgroundKind, PlaneOrientation, UiRadius}, + }, components::Color, Archetype, }; -use re_viewer_context::TypedComponentFallbackProvider; +use re_viewer_context::{SpaceViewStateExt as _, TypedComponentFallbackProvider}; -use crate::SpatialSpaceView3D; +use crate::{ui::SpatialSpaceViewState, SpatialSpaceView3D}; impl TypedComponentFallbackProvider for SpatialSpaceView3D { fn fallback_for(&self, ctx: &re_viewer_context::QueryContext<'_>) -> Color { // Color is a fairly common component, make sure this is the right context. if ctx.archetype_name == Some(Background::name()) { Color::WHITE + } else if ctx.archetype_name == Some(LineGrid3D::name()) { + Color::from_unmultiplied_rgba(200, 200, 200, 200) } else { Color::default() } @@ -24,4 +29,33 @@ impl TypedComponentFallbackProvider for SpatialSpaceView3D { } } -re_viewer_context::impl_component_fallback_provider!(SpatialSpaceView3D => [BackgroundKind, Color]); +impl TypedComponentFallbackProvider for SpatialSpaceView3D { + fn fallback_for(&self, ctx: &re_viewer_context::QueryContext<'_>) -> UiRadius { + if ctx.archetype_name == Some(LineGrid3D::name()) { + // 1 ui unit thickness by default. + 0.5.into() + } else { + 1.0.into() + } + } +} + +impl TypedComponentFallbackProvider for SpatialSpaceView3D { + fn fallback_for(&self, ctx: &re_viewer_context::QueryContext<'_>) -> PlaneOrientation { + let Ok(view_state) = ctx.view_state.downcast_ref::() else { + return PlaneOrientation::default(); + }; + + view_state + .state_3d + .scene_view_coordinates + .and_then(|view_coordinates| view_coordinates.up()) + .map_or(PlaneOrientation::default(), |up| match up.axis { + re_types::view_coordinates::Axis3::X => PlaneOrientation::Yz, + re_types::view_coordinates::Axis3::Y => PlaneOrientation::Xz, + re_types::view_coordinates::Axis3::Z => PlaneOrientation::Xy, + }) + } +} + +re_viewer_context::impl_component_fallback_provider!(SpatialSpaceView3D => [BackgroundKind, Color, UiRadius, PlaneOrientation]); diff --git a/crates/viewer/re_viewer/src/reflection/mod.rs b/crates/viewer/re_viewer/src/reflection/mod.rs index ce58c04cd6c0..1c90df25e8d3 100644 --- a/crates/viewer/re_viewer/src/reflection/mod.rs +++ b/crates/viewer/re_viewer/src/reflection/mod.rs @@ -266,7 +266,7 @@ fn generate_component_reflection() -> Result::name(), ComponentReflection { docstring_md: "Like `Radius`, but in always in ui units.", - custom_placeholder: Some(UiRadius::default().to_arrow2()?), + custom_placeholder: None, datatype: UiRadius::arrow2_datatype(), }, ), From 82a4abb53c6b34e6eba40b43cc020df2023f97ad Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Wed, 27 Nov 2024 15:54:54 +0100 Subject: [PATCH 05/29] enable grid in 3d views, some tweaks, make alpha picker always show up --- .../components/plane_orientation.fbs | 4 +- .../blueprint/components/plane_orientation.rs | 2 +- crates/viewer/re_component_ui/src/color.rs | 5 +- .../viewer/re_renderer/shader/world_grid.wgsl | 2 +- .../viewer/re_space_view_spatial/src/ui_3d.rs | 56 ++++++++++++++++++- .../src/view_3d_properties.rs | 2 +- .../src/view_properties.rs | 4 +- 7 files changed, 64 insertions(+), 11 deletions(-) diff --git a/crates/store/re_types/definitions/rerun/blueprint/components/plane_orientation.fbs b/crates/store/re_types/definitions/rerun/blueprint/components/plane_orientation.fbs index 424c3207d03e..aba3db30ae98 100644 --- a/crates/store/re_types/definitions/rerun/blueprint/components/plane_orientation.fbs +++ b/crates/store/re_types/definitions/rerun/blueprint/components/plane_orientation.fbs @@ -8,9 +8,9 @@ enum PlaneOrientation: ubyte ( Invalid = 0, /// Plane spanned by X and Z axis. - Xz (default), + Xz, /// Plane spanned by Y and Z axis. Yz, /// Plane spanned by X and Y axis. - Xy, + Xy (default), // we default to RFU cameras in the view. } diff --git a/crates/store/re_types/src/blueprint/components/plane_orientation.rs b/crates/store/re_types/src/blueprint/components/plane_orientation.rs index 5795db5aaf56..970aa3310487 100644 --- a/crates/store/re_types/src/blueprint/components/plane_orientation.rs +++ b/crates/store/re_types/src/blueprint/components/plane_orientation.rs @@ -24,13 +24,13 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; #[repr(u8)] pub enum PlaneOrientation { /// Plane spanned by X and Z axis. - #[default] Xz = 1, /// Plane spanned by Y and Z axis. Yz = 2, /// Plane spanned by X and Y axis. + #[default] Xy = 3, } diff --git a/crates/viewer/re_component_ui/src/color.rs b/crates/viewer/re_component_ui/src/color.rs index 48392540adf1..09114a162253 100644 --- a/crates/viewer/re_component_ui/src/color.rs +++ b/crates/viewer/re_component_ui/src/color.rs @@ -19,9 +19,8 @@ fn edit_rgba32_impl(ui: &mut egui::Ui, color: &mut MaybeMutRef<'_, Rgba32>) -> e let response = egui::color_picker::color_edit_button_srgba( ui, &mut edit_color, - // TODO(#1611): No transparency supported right now. - // Once we do we probably need to be more explicit about the component semantics. - egui::color_picker::Alpha::Opaque, + // TODO(#1611): Most of the time this doesn't do anything. Would be great to distinguish that. + egui::color_picker::Alpha::OnlyBlend, ); *color = edit_color.into(); response diff --git a/crates/viewer/re_renderer/shader/world_grid.wgsl b/crates/viewer/re_renderer/shader/world_grid.wgsl index 49f0a0b8fb8b..b9276b61b5ea 100644 --- a/crates/viewer/re_renderer/shader/world_grid.wgsl +++ b/crates/viewer/re_renderer/shader/world_grid.wgsl @@ -18,7 +18,7 @@ struct WorldGridUniformBuffer { var config: WorldGridUniformBuffer; struct VertexOutput { - @builtin(position)W + @builtin(position) position: vec4f, @location(0) diff --git a/crates/viewer/re_space_view_spatial/src/ui_3d.rs b/crates/viewer/re_space_view_spatial/src/ui_3d.rs index 6141ae293402..4a5696d4814e 100644 --- a/crates/viewer/re_space_view_spatial/src/ui_3d.rs +++ b/crates/viewer/re_space_view_spatial/src/ui_3d.rs @@ -13,7 +13,12 @@ use re_space_view::controls::{ ROTATE3D_BUTTON, SPEED_UP_3D_MODIFIER, TRACKED_OBJECT_RESTORE_KEY, }; use re_types::{ - blueprint::archetypes::Background, components::ViewCoordinates, view_coordinates::SignedAxis3, + blueprint::{ + archetypes::{Background, LineGrid3D}, + components::{GridSpacing, PlaneOrientation, UiRadius, Visible}, + }, + components::ViewCoordinates, + view_coordinates::SignedAxis3, }; use re_ui::{ContextExt, ModifiersMarkdown, MouseButtonMarkdown}; use re_viewer_context::{ @@ -660,6 +665,16 @@ impl SpatialSpaceView3D { view_builder.queue_draw(draw_data); } + // Optional 3D line grid. + let grid_config = ViewProperty::from_archetype::( + ctx.blueprint_db(), + ctx.blueprint_query, + query.space_view_id, + ); + if let Some(draw_data) = self.setup_grid_3d(ctx, &grid_config, state)? { + view_builder.queue_draw(draw_data); + } + // Commit ui induced lines. view_builder.queue_draw(line_builder.into_draw_data()?); @@ -694,6 +709,45 @@ impl SpatialSpaceView3D { Ok(()) } + + fn setup_grid_3d( + &self, + ctx: &ViewerContext<'_>, + grid_config: &ViewProperty, + state: &SpatialSpaceViewState, + ) -> Result, SpaceViewSystemExecutionError> + { + if !**grid_config.component_or_fallback::(ctx, self, state)? { + return Ok(None); + } + + let spacing = **grid_config.component_or_fallback::(ctx, self, state)?; + let thickness_ui = + (**grid_config.component_or_fallback::(ctx, self, state)?) * 2.0; + let color = + grid_config.component_or_fallback::(ctx, self, state)?; + let orientation = + grid_config.component_or_fallback::(ctx, self, state)?; + let plane = match orientation { + PlaneOrientation::Xy => re_math::Plane3::XY, + PlaneOrientation::Yz => re_math::Plane3::YZ, + PlaneOrientation::Xz => re_math::Plane3::ZX, + }; + + let Some(render_ctx) = ctx.render_ctx else { + return Ok(None); + }; + + Ok(Some(re_renderer::renderer::WorldGridDrawData::new( + render_ctx, + &re_renderer::renderer::WorldGridConfiguration { + color: color.into(), + plane, + spacing, + thickness_ui, + }, + ))) + } } /// Show center of orbit camera when interacting with camera (it's quite helpful). diff --git a/crates/viewer/re_space_view_spatial/src/view_3d_properties.rs b/crates/viewer/re_space_view_spatial/src/view_3d_properties.rs index a211ee3b64e4..5c37d70c1a72 100644 --- a/crates/viewer/re_space_view_spatial/src/view_3d_properties.rs +++ b/crates/viewer/re_space_view_spatial/src/view_3d_properties.rs @@ -16,7 +16,7 @@ impl TypedComponentFallbackProvider for SpatialSpaceView3D { if ctx.archetype_name == Some(Background::name()) { Color::WHITE } else if ctx.archetype_name == Some(LineGrid3D::name()) { - Color::from_unmultiplied_rgba(200, 200, 200, 200) + Color::from_unmultiplied_rgba(128, 128, 128, 128) } else { Color::default() } diff --git a/crates/viewer/re_viewport_blueprint/src/view_properties.rs b/crates/viewer/re_viewport_blueprint/src/view_properties.rs index 1accc8427470..9c77f8ebf272 100644 --- a/crates/viewer/re_viewport_blueprint/src/view_properties.rs +++ b/crates/viewer/re_viewport_blueprint/src/view_properties.rs @@ -90,7 +90,7 @@ impl ViewProperty { /// Get the value of a specific component or its fallback if the component is not present. // TODO(andreas): Unfortunately we can't use TypedComponentFallbackProvider here because it may not be implemented for all components of interest. // This sadly means that there's a bit of unnecessary back and forth between arrow array and untyped that could be avoided otherwise. - pub fn component_or_fallback( + pub fn component_or_fallback( &self, ctx: &ViewerContext<'_>, fallback_provider: &dyn ComponentFallbackProvider, @@ -103,7 +103,7 @@ impl ViewProperty { } /// Get the component array for a given type or its fallback if the component is not present or empty. - pub fn component_array_or_fallback( + pub fn component_array_or_fallback( &self, ctx: &ViewerContext<'_>, fallback_provider: &dyn ComponentFallbackProvider, From f149015157ecfd454e7c62365bcb7b1a8dcb10f4 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Wed, 27 Nov 2024 16:25:57 +0100 Subject: [PATCH 06/29] introduce plane offset to the world grid --- .../blueprint/archetypes/line_grid_3d.fbs | 17 +-- .../rerun/blueprint/components.fbs | 1 + .../blueprint/components/plane_offset.fbs | 12 ++ .../src/blueprint/archetypes/line_grid3d.rs | 114 ++++++++++------- .../src/blueprint/components/.gitattributes | 1 + .../re_types/src/blueprint/components/mod.rs | 2 + .../src/blueprint/components/plane_offset.rs | 116 ++++++++++++++++++ crates/viewer/re_component_ui/src/lib.rs | 5 +- .../viewer/re_renderer/shader/world_grid.wgsl | 3 + .../viewer/re_space_view_spatial/src/ui_3d.rs | 9 +- .../src/blueprint/validation_gen/mod.rs | 2 + crates/viewer/re_viewer/src/reflection/mod.rs | 19 ++- .../reference/types/views/spatial3d_view.md | 3 +- .../blueprint/archetypes/line_grid3d.cpp | 17 ++- .../blueprint/archetypes/line_grid3d.hpp | 41 ++++--- rerun_cpp/src/rerun/blueprint/components.hpp | 1 + .../rerun/blueprint/components/.gitattributes | 1 + .../blueprint/components/plane_offset.hpp | 74 +++++++++++ .../rerun/blueprint/archetypes/line_grid3d.py | 54 +++++--- .../rerun/blueprint/components/.gitattributes | 1 + .../rerun/blueprint/components/__init__.py | 3 + .../blueprint/components/plane_offset.py | 32 +++++ 22 files changed, 430 insertions(+), 98 deletions(-) create mode 100644 crates/store/re_types/definitions/rerun/blueprint/components/plane_offset.fbs create mode 100644 crates/store/re_types/src/blueprint/components/plane_offset.rs create mode 100644 rerun_cpp/src/rerun/blueprint/components/plane_offset.hpp create mode 100644 rerun_py/rerun_sdk/rerun/blueprint/components/plane_offset.py diff --git a/crates/store/re_types/definitions/rerun/blueprint/archetypes/line_grid_3d.fbs b/crates/store/re_types/definitions/rerun/blueprint/archetypes/line_grid_3d.fbs index 4e2b1770ff55..e5052922c5e0 100644 --- a/crates/store/re_types/definitions/rerun/blueprint/archetypes/line_grid_3d.fbs +++ b/crates/store/re_types/definitions/rerun/blueprint/archetypes/line_grid_3d.fbs @@ -12,19 +12,22 @@ table LineGrid3D ( /// Space between grid lines spacing of one line to the next in scene units. spacing: rerun.blueprint.components.GridSpacing ("attr.rerun.component_optional", nullable, order: 2000); + /// How the grid is oriented. + /// + /// Defaults to whatever plane is determined as the down plane by view coordinates if present. + orientation: rerun.blueprint.components.PlaneOrientation ("attr.rerun.component_optional", nullable, order: 3000); + + /// Offset of the grid along its normal. + offset: rerun.blueprint.components.PlaneOffset ("attr.rerun.component_optional", nullable, order: 4000); + /// How thick the lines should be in ui units. /// /// Default is 0.5 ui unit. - line_radius: rerun.blueprint.components.UiRadius ("attr.rerun.component_optional", nullable, order: 3000); + line_radius: rerun.blueprint.components.UiRadius ("attr.rerun.component_optional", nullable, order: 5000); /// Color used for the grid. /// /// Transparency via alpha channel is supported. /// Defaults to a slightly transparent light gray. - color: rerun.components.Color ("attr.rerun.component_optional", nullable, order: 4000); - - /// How the grid is oriented. - /// - /// Defaults to whatever plane is determined as the down plane by view coordinates if present. - orientation: rerun.blueprint.components.PlaneOrientation ("attr.rerun.component_optional", nullable, order: 5000); + color: rerun.components.Color ("attr.rerun.component_optional", nullable, order: 6000); } diff --git a/crates/store/re_types/definitions/rerun/blueprint/components.fbs b/crates/store/re_types/definitions/rerun/blueprint/components.fbs index 345cd4c113df..2b049eaaf4c8 100644 --- a/crates/store/re_types/definitions/rerun/blueprint/components.fbs +++ b/crates/store/re_types/definitions/rerun/blueprint/components.fbs @@ -18,6 +18,7 @@ include "./components/interactive.fbs"; include "./components/lock_range_during_zoom.fbs"; include "./components/map_provider.fbs"; include "./components/panel_state.fbs"; +include "./components/plane_offset.fbs"; include "./components/plane_orientation.fbs"; include "./components/query_expression.fbs"; include "./components/root_container.fbs"; diff --git a/crates/store/re_types/definitions/rerun/blueprint/components/plane_offset.fbs b/crates/store/re_types/definitions/rerun/blueprint/components/plane_offset.fbs new file mode 100644 index 000000000000..9a6b3008b8b1 --- /dev/null +++ b/crates/store/re_types/definitions/rerun/blueprint/components/plane_offset.fbs @@ -0,0 +1,12 @@ +namespace rerun.blueprint.components; + +/// Offset of a plane along its normal in scene units. +table PlaneOffset ( + "attr.python.aliases": "float", + "attr.python.array_aliases": "npt.ArrayLike", + "attr.rust.derive": "Default", + "attr.rerun.scope": "blueprint" +) { + /// Offset of a plane along its normal in scene units. + distance: rerun.datatypes.Float32 (order: 100); +} diff --git a/crates/store/re_types/src/blueprint/archetypes/line_grid3d.rs b/crates/store/re_types/src/blueprint/archetypes/line_grid3d.rs index 2e43b993235b..9bfb3371c86d 100644 --- a/crates/store/re_types/src/blueprint/archetypes/line_grid3d.rs +++ b/crates/store/re_types/src/blueprint/archetypes/line_grid3d.rs @@ -29,6 +29,14 @@ pub struct LineGrid3D { /// Space between grid lines spacing of one line to the next in scene units. pub spacing: Option, + /// How the grid is oriented. + /// + /// Defaults to whatever plane is determined as the down plane by view coordinates if present. + pub orientation: Option, + + /// Offset of the grid along its normal. + pub offset: Option, + /// How thick the lines should be in ui units. /// /// Default is 0.5 ui unit. @@ -39,11 +47,6 @@ pub struct LineGrid3D { /// Transparency via alpha channel is supported. /// Defaults to a slightly transparent light gray. pub color: Option, - - /// How the grid is oriented. - /// - /// Defaults to whatever plane is determined as the down plane by view coordinates if present. - pub orientation: Option, } impl ::re_types_core::SizeBytes for LineGrid3D { @@ -51,18 +54,20 @@ impl ::re_types_core::SizeBytes for LineGrid3D { fn heap_size_bytes(&self) -> u64 { self.visible.heap_size_bytes() + self.spacing.heap_size_bytes() + + self.orientation.heap_size_bytes() + + self.offset.heap_size_bytes() + self.line_radius.heap_size_bytes() + self.color.heap_size_bytes() - + self.orientation.heap_size_bytes() } #[inline] fn is_pod() -> bool { >::is_pod() && >::is_pod() + && >::is_pod() + && >::is_pod() && >::is_pod() && >::is_pod() - && >::is_pod() } } @@ -72,32 +77,34 @@ static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentName; 0usize]> = static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentName; 1usize]> = once_cell::sync::Lazy::new(|| ["rerun.blueprint.components.LineGrid3DIndicator".into()]); -static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentName; 5usize]> = +static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentName; 6usize]> = once_cell::sync::Lazy::new(|| { [ "rerun.blueprint.components.Visible".into(), "rerun.blueprint.components.GridSpacing".into(), + "rerun.blueprint.components.PlaneOrientation".into(), + "rerun.blueprint.components.PlaneOffset".into(), "rerun.blueprint.components.UiRadius".into(), "rerun.components.Color".into(), - "rerun.blueprint.components.PlaneOrientation".into(), ] }); -static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentName; 6usize]> = +static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentName; 7usize]> = once_cell::sync::Lazy::new(|| { [ "rerun.blueprint.components.LineGrid3DIndicator".into(), "rerun.blueprint.components.Visible".into(), "rerun.blueprint.components.GridSpacing".into(), + "rerun.blueprint.components.PlaneOrientation".into(), + "rerun.blueprint.components.PlaneOffset".into(), "rerun.blueprint.components.UiRadius".into(), "rerun.components.Color".into(), - "rerun.blueprint.components.PlaneOrientation".into(), ] }); impl LineGrid3D { - /// The total number of components in the archetype: 0 required, 1 recommended, 5 optional - pub const NUM_COMPONENTS: usize = 6usize; + /// The total number of components in the archetype: 0 required, 1 recommended, 6 optional + pub const NUM_COMPONENTS: usize = 7usize; } /// Indicator component for the [`LineGrid3D`] [`::re_types_core::Archetype`] @@ -172,6 +179,27 @@ impl ::re_types_core::Archetype for LineGrid3D { } else { None }; + let orientation = if let Some(array) = + arrays_by_name.get("rerun.blueprint.components.PlaneOrientation") + { + ::from_arrow2_opt(&**array) + .with_context("rerun.blueprint.archetypes.LineGrid3D#orientation")? + .into_iter() + .next() + .flatten() + } else { + None + }; + let offset = + if let Some(array) = arrays_by_name.get("rerun.blueprint.components.PlaneOffset") { + ::from_arrow2_opt(&**array) + .with_context("rerun.blueprint.archetypes.LineGrid3D#offset")? + .into_iter() + .next() + .flatten() + } else { + None + }; let line_radius = if let Some(array) = arrays_by_name.get("rerun.blueprint.components.UiRadius") { ::from_arrow2_opt(&**array) @@ -191,23 +219,13 @@ impl ::re_types_core::Archetype for LineGrid3D { } else { None }; - let orientation = if let Some(array) = - arrays_by_name.get("rerun.blueprint.components.PlaneOrientation") - { - ::from_arrow2_opt(&**array) - .with_context("rerun.blueprint.archetypes.LineGrid3D#orientation")? - .into_iter() - .next() - .flatten() - } else { - None - }; Ok(Self { visible, spacing, + orientation, + offset, line_radius, color, - orientation, }) } } @@ -224,13 +242,16 @@ impl ::re_types_core::AsComponents for LineGrid3D { self.spacing .as_ref() .map(|comp| (comp as &dyn ComponentBatch).into()), - self.line_radius + self.orientation .as_ref() .map(|comp| (comp as &dyn ComponentBatch).into()), - self.color + self.offset .as_ref() .map(|comp| (comp as &dyn ComponentBatch).into()), - self.orientation + self.line_radius + .as_ref() + .map(|comp| (comp as &dyn ComponentBatch).into()), + self.color .as_ref() .map(|comp| (comp as &dyn ComponentBatch).into()), ] @@ -249,9 +270,10 @@ impl LineGrid3D { Self { visible: None, spacing: None, + orientation: None, + offset: None, line_radius: None, color: None, - orientation: None, } } @@ -277,6 +299,28 @@ impl LineGrid3D { self } + /// How the grid is oriented. + /// + /// Defaults to whatever plane is determined as the down plane by view coordinates if present. + #[inline] + pub fn with_orientation( + mut self, + orientation: impl Into, + ) -> Self { + self.orientation = Some(orientation.into()); + self + } + + /// Offset of the grid along its normal. + #[inline] + pub fn with_offset( + mut self, + offset: impl Into, + ) -> Self { + self.offset = Some(offset.into()); + self + } + /// How thick the lines should be in ui units. /// /// Default is 0.5 ui unit. @@ -298,16 +342,4 @@ impl LineGrid3D { self.color = Some(color.into()); self } - - /// How the grid is oriented. - /// - /// Defaults to whatever plane is determined as the down plane by view coordinates if present. - #[inline] - pub fn with_orientation( - mut self, - orientation: impl Into, - ) -> Self { - self.orientation = Some(orientation.into()); - self - } } diff --git a/crates/store/re_types/src/blueprint/components/.gitattributes b/crates/store/re_types/src/blueprint/components/.gitattributes index 1abe730df77b..4ac1300d4535 100644 --- a/crates/store/re_types/src/blueprint/components/.gitattributes +++ b/crates/store/re_types/src/blueprint/components/.gitattributes @@ -16,6 +16,7 @@ lock_range_during_zoom.rs linguist-generated=true map_provider.rs linguist-generated=true mod.rs linguist-generated=true panel_state.rs linguist-generated=true +plane_offset.rs linguist-generated=true plane_orientation.rs linguist-generated=true query_expression.rs linguist-generated=true row_share.rs linguist-generated=true diff --git a/crates/store/re_types/src/blueprint/components/mod.rs b/crates/store/re_types/src/blueprint/components/mod.rs index 320a46e1001a..cc8a1bd5c387 100644 --- a/crates/store/re_types/src/blueprint/components/mod.rs +++ b/crates/store/re_types/src/blueprint/components/mod.rs @@ -21,6 +21,7 @@ mod lock_range_during_zoom; mod map_provider; mod panel_state; mod panel_state_ext; +mod plane_offset; mod plane_orientation; mod query_expression; mod row_share; @@ -58,6 +59,7 @@ pub use self::interactive::Interactive; pub use self::lock_range_during_zoom::LockRangeDuringZoom; pub use self::map_provider::MapProvider; pub use self::panel_state::PanelState; +pub use self::plane_offset::PlaneOffset; pub use self::plane_orientation::PlaneOrientation; pub use self::query_expression::QueryExpression; pub use self::row_share::RowShare; diff --git a/crates/store/re_types/src/blueprint/components/plane_offset.rs b/crates/store/re_types/src/blueprint/components/plane_offset.rs new file mode 100644 index 000000000000..3a1fd0170e8d --- /dev/null +++ b/crates/store/re_types/src/blueprint/components/plane_offset.rs @@ -0,0 +1,116 @@ +// 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/blueprint/components/plane_offset.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::ComponentName; +use ::re_types_core::SerializationResult; +use ::re_types_core::{ComponentBatch, MaybeOwnedComponentBatch}; +use ::re_types_core::{DeserializationError, DeserializationResult}; + +/// **Component**: Offset of a plane along its normal in scene units. +#[derive(Clone, Debug, Default)] +pub struct PlaneOffset( + /// Offset of a plane along its normal in scene units. + pub crate::datatypes::Float32, +); + +impl ::re_types_core::SizeBytes for PlaneOffset { + #[inline] + fn heap_size_bytes(&self) -> u64 { + self.0.heap_size_bytes() + } + + #[inline] + fn is_pod() -> bool { + ::is_pod() + } +} + +impl> From for PlaneOffset { + fn from(v: T) -> Self { + Self(v.into()) + } +} + +impl std::borrow::Borrow for PlaneOffset { + #[inline] + fn borrow(&self) -> &crate::datatypes::Float32 { + &self.0 + } +} + +impl std::ops::Deref for PlaneOffset { + type Target = crate::datatypes::Float32; + + #[inline] + fn deref(&self) -> &crate::datatypes::Float32 { + &self.0 + } +} + +impl std::ops::DerefMut for PlaneOffset { + #[inline] + fn deref_mut(&mut self) -> &mut crate::datatypes::Float32 { + &mut self.0 + } +} + +::re_types_core::macros::impl_into_cow!(PlaneOffset); + +impl ::re_types_core::Loggable for PlaneOffset { + #[inline] + fn arrow_datatype() -> arrow::datatypes::DataType { + crate::datatypes::Float32::arrow_datatype() + } + + fn to_arrow_opt<'a>( + data: impl IntoIterator>>>, + ) -> SerializationResult + where + Self: Clone + 'a, + { + crate::datatypes::Float32::to_arrow_opt(data.into_iter().map(|datum| { + datum.map(|datum| match datum.into() { + ::std::borrow::Cow::Borrowed(datum) => ::std::borrow::Cow::Borrowed(&datum.0), + ::std::borrow::Cow::Owned(datum) => ::std::borrow::Cow::Owned(datum.0), + }) + })) + } + + fn from_arrow2_opt( + arrow_data: &dyn arrow2::array::Array, + ) -> DeserializationResult>> + where + Self: Sized, + { + crate::datatypes::Float32::from_arrow2_opt(arrow_data) + .map(|v| v.into_iter().map(|v| v.map(Self)).collect()) + } + + #[inline] + fn from_arrow2(arrow_data: &dyn arrow2::array::Array) -> DeserializationResult> + where + Self: Sized, + { + crate::datatypes::Float32::from_arrow2(arrow_data) + .map(|v| v.into_iter().map(Self).collect()) + } +} + +impl ::re_types_core::Component for PlaneOffset { + #[inline] + fn name() -> ComponentName { + "rerun.blueprint.components.PlaneOffset".into() + } +} diff --git a/crates/viewer/re_component_ui/src/lib.rs b/crates/viewer/re_component_ui/src/lib.rs index feb2b523b497..6ea5900092ef 100644 --- a/crates/viewer/re_component_ui/src/lib.rs +++ b/crates/viewer/re_component_ui/src/lib.rs @@ -34,8 +34,8 @@ use datatype_uis::{ use re_types::{ blueprint::components::{ - BackgroundKind, Corner2D, GridSpacing, LockRangeDuringZoom, MapProvider, PlaneOrientation, - UiRadius, ViewFit, Visible, + BackgroundKind, Corner2D, GridSpacing, LockRangeDuringZoom, MapProvider, PlaneOffset, + PlaneOrientation, UiRadius, ViewFit, Visible, }, components::{ AggregationPolicy, AlbedoFactor, AxisLength, Color, DepthMeter, DrawOrder, FillMode, @@ -80,6 +80,7 @@ pub fn create_component_ui_registry() -> re_viewer_context::ComponentUiRegistry // float min-max components: registry.add_singleline_edit_or_view::(edit_f32_min_to_max_float); + registry.add_singleline_edit_or_view::(edit_f32_min_to_max_float); // float 0-1 components: registry.add_singleline_edit_or_view::(edit_f32_zero_to_one); diff --git a/crates/viewer/re_renderer/shader/world_grid.wgsl b/crates/viewer/re_renderer/shader/world_grid.wgsl index b9276b61b5ea..960ce177a5c1 100644 --- a/crates/viewer/re_renderer/shader/world_grid.wgsl +++ b/crates/viewer/re_renderer/shader/world_grid.wgsl @@ -12,6 +12,9 @@ struct WorldGridUniformBuffer { /// How thick the lines are in UI units. thickness_ui: f32, + + /// Offset of the grid along its normal. + normal_offset: f32, } @group(1) @binding(0) diff --git a/crates/viewer/re_space_view_spatial/src/ui_3d.rs b/crates/viewer/re_space_view_spatial/src/ui_3d.rs index 4a5696d4814e..d3624ee390c0 100644 --- a/crates/viewer/re_space_view_spatial/src/ui_3d.rs +++ b/crates/viewer/re_space_view_spatial/src/ui_3d.rs @@ -15,7 +15,7 @@ use re_space_view::controls::{ use re_types::{ blueprint::{ archetypes::{Background, LineGrid3D}, - components::{GridSpacing, PlaneOrientation, UiRadius, Visible}, + components::{GridSpacing, PlaneOffset, PlaneOrientation, UiRadius, Visible}, }, components::ViewCoordinates, view_coordinates::SignedAxis3, @@ -728,10 +728,11 @@ impl SpatialSpaceView3D { grid_config.component_or_fallback::(ctx, self, state)?; let orientation = grid_config.component_or_fallback::(ctx, self, state)?; + let normal_offset = **grid_config.component_or_fallback::(ctx, self, state)?; let plane = match orientation { - PlaneOrientation::Xy => re_math::Plane3::XY, - PlaneOrientation::Yz => re_math::Plane3::YZ, - PlaneOrientation::Xz => re_math::Plane3::ZX, + PlaneOrientation::Xy => re_math::Plane3::from_normal_dist(glam::Vec3::Z, normal_offset), + PlaneOrientation::Yz => re_math::Plane3::from_normal_dist(glam::Vec3::X, normal_offset), + PlaneOrientation::Xz => re_math::Plane3::from_normal_dist(glam::Vec3::Y, normal_offset), }; let Some(render_ctx) = ctx.render_ctx else { diff --git a/crates/viewer/re_viewer/src/blueprint/validation_gen/mod.rs b/crates/viewer/re_viewer/src/blueprint/validation_gen/mod.rs index 9e9ad447ea97..3c42dcb8b65e 100644 --- a/crates/viewer/re_viewer/src/blueprint/validation_gen/mod.rs +++ b/crates/viewer/re_viewer/src/blueprint/validation_gen/mod.rs @@ -15,6 +15,7 @@ pub use re_types::blueprint::components::Interactive; pub use re_types::blueprint::components::LockRangeDuringZoom; pub use re_types::blueprint::components::MapProvider; pub use re_types::blueprint::components::PanelState; +pub use re_types::blueprint::components::PlaneOffset; pub use re_types::blueprint::components::PlaneOrientation; pub use re_types::blueprint::components::QueryExpression; pub use re_types::blueprint::components::RowShare; @@ -60,6 +61,7 @@ pub fn is_valid_blueprint(blueprint: &EntityDb) -> bool { && validate_component::(blueprint) && validate_component::(blueprint) && validate_component::(blueprint) + && validate_component::(blueprint) && validate_component::(blueprint) && validate_component::(blueprint) && validate_component::(blueprint) diff --git a/crates/viewer/re_viewer/src/reflection/mod.rs b/crates/viewer/re_viewer/src/reflection/mod.rs index 1c90df25e8d3..ff67f7581250 100644 --- a/crates/viewer/re_viewer/src/reflection/mod.rs +++ b/crates/viewer/re_viewer/src/reflection/mod.rs @@ -180,6 +180,14 @@ fn generate_component_reflection() -> Result::name(), + ComponentReflection { + docstring_md: "Offset of a plane along its normal in scene units.", + custom_placeholder: Some(PlaneOffset::default().to_arrow2()?), + datatype: PlaneOffset::arrow2_datatype(), + }, + ), ( ::name(), ComponentReflection { @@ -1969,6 +1977,13 @@ fn generate_archetype_reflection() -> ArchetypeReflectionMap { "Spacing", docstring_md : "Space between grid lines spacing of one line to the next in scene units.", is_required : false, }, ArchetypeFieldReflection { component_name : + "rerun.blueprint.components.PlaneOrientation".into(), display_name : + "Orientation", docstring_md : + "How the grid is oriented.\n\nDefaults to whatever plane is determined as the down plane by view coordinates if present.", + is_required : false, }, ArchetypeFieldReflection { component_name : + "rerun.blueprint.components.PlaneOffset".into(), display_name : + "Offset", docstring_md : "Offset of the grid along its normal.", + is_required : false, }, ArchetypeFieldReflection { component_name : "rerun.blueprint.components.UiRadius".into(), display_name : "Line radius", docstring_md : "How thick the lines should be in ui units.\n\nDefault is 0.5 ui unit.", @@ -1976,10 +1991,6 @@ fn generate_archetype_reflection() -> ArchetypeReflectionMap { "rerun.components.Color".into(), display_name : "Color", docstring_md : "Color used for the grid.\n\nTransparency via alpha channel is supported.\nDefaults to a slightly transparent light gray.", - is_required : false, }, ArchetypeFieldReflection { component_name : - "rerun.blueprint.components.PlaneOrientation".into(), display_name : - "Orientation", docstring_md : - "How the grid is oriented.\n\nDefaults to whatever plane is determined as the down plane by view coordinates if present.", is_required : false, }, ], }, diff --git a/docs/content/reference/types/views/spatial3d_view.md b/docs/content/reference/types/views/spatial3d_view.md index 5ff22ffa2e8c..546e8dc017a6 100644 --- a/docs/content/reference/types/views/spatial3d_view.md +++ b/docs/content/reference/types/views/spatial3d_view.md @@ -17,9 +17,10 @@ Configuration for the 3D line grid. * `visible`: Whether the grid is visible. * `spacing`: Space between grid lines spacing of one line to the next in scene units. +* `orientation`: How the grid is oriented. +* `offset`: Offset of the grid along its normal. * `line_radius`: How thick the lines should be in ui units. * `color`: Color used for the grid. -* `orientation`: How the grid is oriented. ### `time_ranges` Configures which range on each timeline is shown by this view (unless specified differently per entity). diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.cpp b/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.cpp index b7d5e2a8d457..3a7f27a71485 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.cpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.cpp @@ -14,7 +14,7 @@ namespace rerun { ) { using namespace blueprint::archetypes; std::vector cells; - cells.reserve(6); + cells.reserve(7); if (archetype.visible.has_value()) { auto result = ComponentBatch::from_loggable(archetype.visible.value()); @@ -26,6 +26,16 @@ namespace rerun { RR_RETURN_NOT_OK(result.error); cells.push_back(std::move(result.value)); } + if (archetype.orientation.has_value()) { + auto result = ComponentBatch::from_loggable(archetype.orientation.value()); + RR_RETURN_NOT_OK(result.error); + cells.push_back(std::move(result.value)); + } + if (archetype.offset.has_value()) { + auto result = ComponentBatch::from_loggable(archetype.offset.value()); + RR_RETURN_NOT_OK(result.error); + cells.push_back(std::move(result.value)); + } if (archetype.line_radius.has_value()) { auto result = ComponentBatch::from_loggable(archetype.line_radius.value()); RR_RETURN_NOT_OK(result.error); @@ -36,11 +46,6 @@ namespace rerun { RR_RETURN_NOT_OK(result.error); cells.push_back(std::move(result.value)); } - if (archetype.orientation.has_value()) { - auto result = ComponentBatch::from_loggable(archetype.orientation.value()); - RR_RETURN_NOT_OK(result.error); - cells.push_back(std::move(result.value)); - } { auto indicator = LineGrid3D::IndicatorComponent(); auto result = ComponentBatch::from_loggable(indicator); diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.hpp b/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.hpp index 0898bede41ad..b66da9203486 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.hpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.hpp @@ -4,6 +4,7 @@ #pragma once #include "../../blueprint/components/grid_spacing.hpp" +#include "../../blueprint/components/plane_offset.hpp" #include "../../blueprint/components/plane_orientation.hpp" #include "../../blueprint/components/ui_radius.hpp" #include "../../blueprint/components/visible.hpp" @@ -30,6 +31,14 @@ namespace rerun::blueprint::archetypes { /// Space between grid lines spacing of one line to the next in scene units. std::optional spacing; + /// How the grid is oriented. + /// + /// Defaults to whatever plane is determined as the down plane by view coordinates if present. + std::optional orientation; + + /// Offset of the grid along its normal. + std::optional offset; + /// How thick the lines should be in ui units. /// /// Default is 0.5 ui unit. @@ -41,11 +50,6 @@ namespace rerun::blueprint::archetypes { /// Defaults to a slightly transparent light gray. std::optional color; - /// How the grid is oriented. - /// - /// Defaults to whatever plane is determined as the down plane by view coordinates if present. - std::optional orientation; - public: static constexpr const char IndicatorComponentName[] = "rerun.blueprint.components.LineGrid3DIndicator"; @@ -73,6 +77,23 @@ namespace rerun::blueprint::archetypes { RR_WITH_MAYBE_UNINITIALIZED_DISABLED(return std::move(*this);) } + /// How the grid is oriented. + /// + /// Defaults to whatever plane is determined as the down plane by view coordinates if present. + LineGrid3D with_orientation(rerun::blueprint::components::PlaneOrientation _orientation + ) && { + orientation = std::move(_orientation); + // See: https://github.com/rerun-io/rerun/issues/4027 + RR_WITH_MAYBE_UNINITIALIZED_DISABLED(return std::move(*this);) + } + + /// Offset of the grid along its normal. + LineGrid3D with_offset(rerun::blueprint::components::PlaneOffset _offset) && { + offset = std::move(_offset); + // See: https://github.com/rerun-io/rerun/issues/4027 + RR_WITH_MAYBE_UNINITIALIZED_DISABLED(return std::move(*this);) + } + /// How thick the lines should be in ui units. /// /// Default is 0.5 ui unit. @@ -91,16 +112,6 @@ namespace rerun::blueprint::archetypes { // See: https://github.com/rerun-io/rerun/issues/4027 RR_WITH_MAYBE_UNINITIALIZED_DISABLED(return std::move(*this);) } - - /// How the grid is oriented. - /// - /// Defaults to whatever plane is determined as the down plane by view coordinates if present. - LineGrid3D with_orientation(rerun::blueprint::components::PlaneOrientation _orientation - ) && { - orientation = std::move(_orientation); - // See: https://github.com/rerun-io/rerun/issues/4027 - RR_WITH_MAYBE_UNINITIALIZED_DISABLED(return std::move(*this);) - } }; } // namespace rerun::blueprint::archetypes diff --git a/rerun_cpp/src/rerun/blueprint/components.hpp b/rerun_cpp/src/rerun/blueprint/components.hpp index 0bd8e4a7887f..9db96efea076 100644 --- a/rerun_cpp/src/rerun/blueprint/components.hpp +++ b/rerun_cpp/src/rerun/blueprint/components.hpp @@ -20,6 +20,7 @@ #include "blueprint/components/lock_range_during_zoom.hpp" #include "blueprint/components/map_provider.hpp" #include "blueprint/components/panel_state.hpp" +#include "blueprint/components/plane_offset.hpp" #include "blueprint/components/plane_orientation.hpp" #include "blueprint/components/query_expression.hpp" #include "blueprint/components/root_container.hpp" diff --git a/rerun_cpp/src/rerun/blueprint/components/.gitattributes b/rerun_cpp/src/rerun/blueprint/components/.gitattributes index 1ef9d20500bb..ba91739ef669 100644 --- a/rerun_cpp/src/rerun/blueprint/components/.gitattributes +++ b/rerun_cpp/src/rerun/blueprint/components/.gitattributes @@ -24,6 +24,7 @@ map_provider.cpp linguist-generated=true map_provider.hpp linguist-generated=true panel_state.cpp linguist-generated=true panel_state.hpp linguist-generated=true +plane_offset.hpp linguist-generated=true plane_orientation.cpp linguist-generated=true plane_orientation.hpp linguist-generated=true query_expression.hpp linguist-generated=true diff --git a/rerun_cpp/src/rerun/blueprint/components/plane_offset.hpp b/rerun_cpp/src/rerun/blueprint/components/plane_offset.hpp new file mode 100644 index 000000000000..e30aa1715701 --- /dev/null +++ b/rerun_cpp/src/rerun/blueprint/components/plane_offset.hpp @@ -0,0 +1,74 @@ +// 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/blueprint/components/plane_offset.fbs". + +#pragma once + +#include "../../datatypes/float32.hpp" +#include "../../result.hpp" + +#include +#include + +namespace rerun::blueprint::components { + /// **Component**: Offset of a plane along its normal in scene units. + struct PlaneOffset { + /// Offset of a plane along its normal in scene units. + rerun::datatypes::Float32 distance; + + public: + PlaneOffset() = default; + + PlaneOffset(rerun::datatypes::Float32 distance_) : distance(distance_) {} + + PlaneOffset& operator=(rerun::datatypes::Float32 distance_) { + distance = distance_; + return *this; + } + + PlaneOffset(float value_) : distance(value_) {} + + PlaneOffset& operator=(float value_) { + distance = value_; + return *this; + } + + /// Cast to the underlying Float32 datatype + operator rerun::datatypes::Float32() const { + return distance; + } + }; +} // namespace rerun::blueprint::components + +namespace rerun { + static_assert(sizeof(rerun::datatypes::Float32) == sizeof(blueprint::components::PlaneOffset)); + + /// \private + template <> + struct Loggable { + static constexpr const char Name[] = "rerun.blueprint.components.PlaneOffset"; + + /// Returns the arrow data type this type corresponds to. + static const std::shared_ptr& arrow_datatype() { + return Loggable::arrow_datatype(); + } + + /// Serializes an array of `rerun::blueprint:: components::PlaneOffset` into an arrow array. + static Result> to_arrow( + const blueprint::components::PlaneOffset* instances, size_t num_instances + ) { + if (num_instances == 0) { + return Loggable::to_arrow(nullptr, 0); + } else if (instances == nullptr) { + return rerun::Error( + ErrorCode::UnexpectedNullArgument, + "Passed array instances is null when num_elements> 0." + ); + } else { + return Loggable::to_arrow( + &instances->distance, + num_instances + ); + } + } + }; +} // namespace rerun diff --git a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/line_grid3d.py b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/line_grid3d.py index b97765275e2b..e3f003243445 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/line_grid3d.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/line_grid3d.py @@ -28,9 +28,10 @@ def __init__( *, visible: datatypes.BoolLike | None = None, spacing: datatypes.Float32Like | None = None, + orientation: blueprint_components.PlaneOrientationLike | None = None, + offset: datatypes.Float32Like | None = None, line_radius: datatypes.Float32Like | None = None, color: datatypes.Rgba32Like | None = None, - orientation: blueprint_components.PlaneOrientationLike | None = None, ): """ Create a new instance of the LineGrid3D archetype. @@ -43,6 +44,12 @@ def __init__( Defaults to true. spacing: Space between grid lines spacing of one line to the next in scene units. + orientation: + How the grid is oriented. + + Defaults to whatever plane is determined as the down plane by view coordinates if present. + offset: + Offset of the grid along its normal. line_radius: How thick the lines should be in ui units. @@ -52,17 +59,18 @@ def __init__( Transparency via alpha channel is supported. Defaults to a slightly transparent light gray. - orientation: - How the grid is oriented. - - Defaults to whatever plane is determined as the down plane by view coordinates if present. """ # You can define your own __init__ function as a member of LineGrid3DExt in line_grid3d_ext.py with catch_and_log_exceptions(context=self.__class__.__name__): self.__attrs_init__( - visible=visible, spacing=spacing, line_radius=line_radius, color=color, orientation=orientation + visible=visible, + spacing=spacing, + orientation=orientation, + offset=offset, + line_radius=line_radius, + color=color, ) return self.__attrs_clear__() @@ -72,9 +80,10 @@ def __attrs_clear__(self) -> None: self.__attrs_init__( visible=None, # type: ignore[arg-type] spacing=None, # type: ignore[arg-type] + orientation=None, # type: ignore[arg-type] + offset=None, # type: ignore[arg-type] line_radius=None, # type: ignore[arg-type] color=None, # type: ignore[arg-type] - orientation=None, # type: ignore[arg-type] ) @classmethod @@ -104,6 +113,26 @@ def _clear(cls) -> LineGrid3D: # # (Docstring intentionally commented out to hide this field from the docs) + orientation: blueprint_components.PlaneOrientationBatch | None = field( + metadata={"component": "optional"}, + default=None, + converter=blueprint_components.PlaneOrientationBatch._optional, # type: ignore[misc] + ) + # How the grid is oriented. + # + # Defaults to whatever plane is determined as the down plane by view coordinates if present. + # + # (Docstring intentionally commented out to hide this field from the docs) + + offset: blueprint_components.PlaneOffsetBatch | None = field( + metadata={"component": "optional"}, + default=None, + converter=blueprint_components.PlaneOffsetBatch._optional, # type: ignore[misc] + ) + # Offset of the grid along its normal. + # + # (Docstring intentionally commented out to hide this field from the docs) + line_radius: blueprint_components.UiRadiusBatch | None = field( metadata={"component": "optional"}, default=None, @@ -127,16 +156,5 @@ def _clear(cls) -> LineGrid3D: # # (Docstring intentionally commented out to hide this field from the docs) - orientation: blueprint_components.PlaneOrientationBatch | None = field( - metadata={"component": "optional"}, - default=None, - converter=blueprint_components.PlaneOrientationBatch._optional, # type: ignore[misc] - ) - # How the grid is oriented. - # - # Defaults to whatever plane is determined as the down plane by view coordinates if present. - # - # (Docstring intentionally commented out to hide this field from the docs) - __str__ = Archetype.__str__ __repr__ = Archetype.__repr__ # type: ignore[assignment] diff --git a/rerun_py/rerun_sdk/rerun/blueprint/components/.gitattributes b/rerun_py/rerun_sdk/rerun/blueprint/components/.gitattributes index b6873b65b5f7..9668112db835 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/components/.gitattributes +++ b/rerun_py/rerun_sdk/rerun/blueprint/components/.gitattributes @@ -20,6 +20,7 @@ interactive.py linguist-generated=true lock_range_during_zoom.py linguist-generated=true map_provider.py linguist-generated=true panel_state.py linguist-generated=true +plane_offset.py linguist-generated=true plane_orientation.py linguist-generated=true query_expression.py linguist-generated=true root_container.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 31f2ccd28d38..267a38176fd9 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/components/__init__.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/components/__init__.py @@ -20,6 +20,7 @@ from .lock_range_during_zoom import LockRangeDuringZoom, LockRangeDuringZoomBatch from .map_provider import MapProvider, MapProviderArrayLike, MapProviderBatch, MapProviderLike from .panel_state import PanelState, PanelStateArrayLike, PanelStateBatch, PanelStateLike +from .plane_offset import PlaneOffset, PlaneOffsetBatch from .plane_orientation import PlaneOrientation, PlaneOrientationArrayLike, PlaneOrientationBatch, PlaneOrientationLike from .query_expression import QueryExpression, QueryExpressionBatch from .root_container import RootContainer, RootContainerBatch @@ -86,6 +87,8 @@ "PanelStateArrayLike", "PanelStateBatch", "PanelStateLike", + "PlaneOffset", + "PlaneOffsetBatch", "PlaneOrientation", "PlaneOrientationArrayLike", "PlaneOrientationBatch", diff --git a/rerun_py/rerun_sdk/rerun/blueprint/components/plane_offset.py b/rerun_py/rerun_sdk/rerun/blueprint/components/plane_offset.py new file mode 100644 index 000000000000..1b89b6a00c2d --- /dev/null +++ b/rerun_py/rerun_sdk/rerun/blueprint/components/plane_offset.py @@ -0,0 +1,32 @@ +# 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/blueprint/components/plane_offset.fbs". + +# You can extend this class by creating a "PlaneOffsetExt" class in "plane_offset_ext.py". + +from __future__ import annotations + +from ... import datatypes +from ..._baseclasses import ( + ComponentBatchMixin, + ComponentMixin, +) + +__all__ = ["PlaneOffset", "PlaneOffsetBatch"] + + +class PlaneOffset(datatypes.Float32, ComponentMixin): + """**Component**: Offset of a plane along its normal in scene units.""" + + _BATCH_TYPE = None + # You can define your own __init__ function as a member of PlaneOffsetExt in plane_offset_ext.py + + # Note: there are no fields here because PlaneOffset delegates to datatypes.Float32 + pass + + +class PlaneOffsetBatch(datatypes.Float32Batch, ComponentBatchMixin): + _COMPONENT_NAME: str = "rerun.blueprint.components.PlaneOffset" + + +# This is patched in late to avoid circular dependencies. +PlaneOffset._BATCH_TYPE = PlaneOffsetBatch # type: ignore[assignment] From 3cdd77276ec7f157479e773a909af47a997bc83f Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Wed, 27 Nov 2024 18:17:18 +0100 Subject: [PATCH 07/29] lint fix --- .../rerun/blueprint/components/plane_orientation.fbs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/store/re_types/definitions/rerun/blueprint/components/plane_orientation.fbs b/crates/store/re_types/definitions/rerun/blueprint/components/plane_orientation.fbs index aba3db30ae98..b4a44b97e309 100644 --- a/crates/store/re_types/definitions/rerun/blueprint/components/plane_orientation.fbs +++ b/crates/store/re_types/definitions/rerun/blueprint/components/plane_orientation.fbs @@ -9,8 +9,10 @@ enum PlaneOrientation: ubyte ( /// Plane spanned by X and Z axis. Xz, + /// Plane spanned by Y and Z axis. Yz, + /// Plane spanned by X and Y axis. Xy (default), // we default to RFU cameras in the view. } From 8f97060d49acc5d7710fc17dfa987e4cb3dfa5b9 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Thu, 28 Nov 2024 11:44:32 +0100 Subject: [PATCH 08/29] infinite cardinal scales --- .../viewer/re_renderer/shader/world_grid.wgsl | 38 ++++++++++++------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/crates/viewer/re_renderer/shader/world_grid.wgsl b/crates/viewer/re_renderer/shader/world_grid.wgsl index 960ce177a5c1..d9d2891260cf 100644 --- a/crates/viewer/re_renderer/shader/world_grid.wgsl +++ b/crates/viewer/re_renderer/shader/world_grid.wgsl @@ -26,6 +26,9 @@ struct VertexOutput { @location(0) scaled_world_plane_position: vec2f, + + @location(1) @interpolate(flat) // Result doesn't differ per vertex. + next_cardinality_interpolation: f32, }; // We have to make up some world space geometry which then necessarily gets a limited size. @@ -58,7 +61,15 @@ fn main_vs(@builtin(vertex_index) v_idx: u32) -> VertexOutput { let world_position = config.plane.normal * -config.plane.distance + plane_x_axis * shifted_plane_position.x + plane_y_axis * shifted_plane_position.y; out.position = frame.projection_from_world * vec4f(world_position, 1.0); - out.scaled_world_plane_position = shifted_plane_position / config.spacing; + + // Determine which "scales" of the grid we want to show. We want to show factor 1, 10, 100, 1000, etc. + let camera_plane_distance_world = distance_to_plane(config.plane, frame.camera_position); + let camera_plane_distance_grid_units = camera_plane_distance_world / config.spacing; + let line_cardinality = max(log2(camera_plane_distance_grid_units) / log2(10.0) - 0.9, 0.0); // -0.9 instead of 1.0 so we always see a little bit of the next level even if we're very close. + let line_base_cardinality = floor(line_cardinality); + let line_spacing_factor = pow(10.0, line_base_cardinality); + out.scaled_world_plane_position = shifted_plane_position / (config.spacing * line_spacing_factor); + out.next_cardinality_interpolation = line_cardinality - line_base_cardinality; return out; } @@ -71,19 +82,20 @@ fn calc_distance_to_grid_line(scaled_world_plane_position: vec2f) -> vec2f { @fragment fn main_fs(in: VertexOutput) -> @location(0) vec4f { - // Most basics are very well explained by Ben Golus here: https://bgolus.medium.com/the-best-darn-grid-shader-yet-727f9278b9d8 + // Most basics of determining a basic pixel space grid are very well explained by Ben Golus here: https://bgolus.medium.com/the-best-darn-grid-shader-yet-727f9278b9d8 // We're not actually implementing the "pristine grid shader" which is a grid with world space thickness, // but rather the pixel space grid, which is a lot simpler, but happens to be also described very well in this article. // Distance to a grid line in x and y ranging from 0 to 1. - let distance_to_grid_line = calc_distance_to_grid_line(in.scaled_world_plane_position); + let distance_to_grid_line_base = calc_distance_to_grid_line(in.scaled_world_plane_position); // Figure out the how wide the lines are in this "draw space". let plane_unit_pixel_derivative = fwidthFine(in.scaled_world_plane_position); let line_anti_alias = plane_unit_pixel_derivative; let width_in_pixels = config.thickness_ui * frame.pixels_from_point; let width_in_grid_units = width_in_pixels * plane_unit_pixel_derivative; - var intensity_regular = linearstep2(width_in_grid_units + line_anti_alias, width_in_grid_units - line_anti_alias, distance_to_grid_line); + var intensity_base = linearstep2(width_in_grid_units + line_anti_alias, width_in_grid_units - line_anti_alias, + distance_to_grid_line_base); // Fade lines that get too close to each other. // Once the number of pixels per line (== from one line to the next) is below a threshold fade them out. @@ -95,24 +107,23 @@ fn main_fs(in: VertexOutput) -> @location(0) vec4f { // // Tried smoothstep here, but didn't feel right even with lots of range tweaking. let screen_space_line_spacing = 1.0 / max(width_in_grid_units.x, width_in_grid_units.y); - let grid_closeness_fade = linearstep(1.0, 10.0, screen_space_line_spacing); - intensity_regular *= grid_closeness_fade; + let grid_closeness_fade = linearstep(2.0, 10.0, screen_space_line_spacing); + intensity_base *= grid_closeness_fade; // Every tenth line is a more intense, we call those "cardinal" lines. // Experimented previously with more levels of cardinal lines, but it gets too busy: // It seems that if we want to go down this path, we should ensure that there's only two levels of lines on screen at a time. - const CARDINAL_LINE_FACTOR: f32 = 10.0; - let distance_to_grid_line_cardinal = calc_distance_to_grid_line(in.scaled_world_plane_position * (1.0 / CARDINAL_LINE_FACTOR)); - var cardinal_line_intensity = linearstep2(width_in_grid_units + line_anti_alias, width_in_grid_units - line_anti_alias, - distance_to_grid_line_cardinal * CARDINAL_LINE_FACTOR); - let cardinal_grid_closeness_fade = linearstep(2.0, 10.0, screen_space_line_spacing * CARDINAL_LINE_FACTOR); // Fade cardinal lines a little bit earlier (because it looks nicer) - cardinal_line_intensity *= cardinal_grid_closeness_fade; + let distance_to_grid_line_cardinal = calc_distance_to_grid_line(in.scaled_world_plane_position * 0.1); + var intensity_cardinal = linearstep2(width_in_grid_units + line_anti_alias, width_in_grid_units - line_anti_alias, + distance_to_grid_line_cardinal * 10.0); + let cardinal_grid_closeness_fade = linearstep(2.0, 10.0, screen_space_line_spacing * 10.0); // Fade cardinal lines a little bit earlier (because it looks nicer) + intensity_cardinal *= cardinal_grid_closeness_fade; // Combine all lines. // // Lerp for cardinal & regular. // This way we don't break anti-aliasing (as addition would!), mute the regular lines, and make cardinals weaker when there's no regular to support them. - let cardinal_and_regular = mix(intensity_regular, cardinal_line_intensity, 0.4); + let cardinal_and_regular = mix(intensity_base, intensity_cardinal, in.next_cardinality_interpolation); // X and Y are combined like akin to premultiplied alpha operations. let intensity_combined = saturate(cardinal_and_regular.x * (1.0 - cardinal_and_regular.y) + cardinal_and_regular.y); @@ -120,6 +131,7 @@ fn main_fs(in: VertexOutput) -> @location(0) vec4f { return config.color * intensity_combined; // Useful debugging visualizations: + //return vec4f(line_cardinality - line_base_cardinality, 0.0, 0.0, 1.0); //return vec4f(intensity_combined); //return vec4f(grid_closeness_fade, cardinal_grid_closeness_fade, 0.0, 1.0); } From 2037074f0e57d350940df75dca40c409d2f08790 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Thu, 28 Nov 2024 13:56:01 +0100 Subject: [PATCH 09/29] improve handling of large scenes --- .../viewer/re_renderer/shader/world_grid.wgsl | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/crates/viewer/re_renderer/shader/world_grid.wgsl b/crates/viewer/re_renderer/shader/world_grid.wgsl index d9d2891260cf..a6b0c144817e 100644 --- a/crates/viewer/re_renderer/shader/world_grid.wgsl +++ b/crates/viewer/re_renderer/shader/world_grid.wgsl @@ -31,13 +31,6 @@ struct VertexOutput { next_cardinality_interpolation: f32, }; -// We have to make up some world space geometry which then necessarily gets a limited size. -// Putting a too high number here makes things break down because of floating point inaccuracies. -// But arguably at that point we're potentially doomed either way since precision will break down in other parts of the rendering as well. -// -// This is the main drawback of the plane approach over the screen space filling one. -const PLANE_GEOMETRY_SIZE: f32 = 10000.0; - // Spans a large quad where centered around the camera. // // This gives us the "canvas" to drawn the grid on. @@ -46,8 +39,14 @@ const PLANE_GEOMETRY_SIZE: f32 = 10000.0; @vertex fn main_vs(@builtin(vertex_index) v_idx: u32) -> VertexOutput { var out: VertexOutput; + let camera_plane_distance_world = distance_to_plane(config.plane, frame.camera_position); + + // Scale the plane geometry based on the distance to the camera. + // This preserves relative precision MUCH better than a fixed scale. + let plane_geometry_size = 1000.0 * camera_plane_distance_world; - var plane_position = (vec2f(f32(v_idx / 2u), f32(v_idx % 2u)) * 2.0 - 1.0) * PLANE_GEOMETRY_SIZE; + // 2D position on the plane. + let plane_position = (vec2f(f32(v_idx / 2u), f32(v_idx % 2u)) * 2.0 - 1.0) * plane_geometry_size; // Make up x and y axis for the plane. let plane_y_axis = normalize(cross(config.plane.normal, select(vec3f(1.0, 0.0, 0.0), vec3f(0.0, 1.0, 0.0), config.plane.normal.x != 0.0))); @@ -59,11 +58,9 @@ fn main_vs(@builtin(vertex_index) v_idx: u32) -> VertexOutput { // Compute world position from shifted plane position. let world_position = config.plane.normal * -config.plane.distance + plane_x_axis * shifted_plane_position.x + plane_y_axis * shifted_plane_position.y; - out.position = frame.projection_from_world * vec4f(world_position, 1.0); // Determine which "scales" of the grid we want to show. We want to show factor 1, 10, 100, 1000, etc. - let camera_plane_distance_world = distance_to_plane(config.plane, frame.camera_position); let camera_plane_distance_grid_units = camera_plane_distance_world / config.spacing; let line_cardinality = max(log2(camera_plane_distance_grid_units) / log2(10.0) - 0.9, 0.0); // -0.9 instead of 1.0 so we always see a little bit of the next level even if we're very close. let line_base_cardinality = floor(line_cardinality); @@ -127,7 +124,6 @@ fn main_fs(in: VertexOutput) -> @location(0) vec4f { // X and Y are combined like akin to premultiplied alpha operations. let intensity_combined = saturate(cardinal_and_regular.x * (1.0 - cardinal_and_regular.y) + cardinal_and_regular.y); - return config.color * intensity_combined; // Useful debugging visualizations: From 8d10baf67d7f6cfffb6ff2ac0b5bf0431e32aad5 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Tue, 3 Dec 2024 11:26:15 +0100 Subject: [PATCH 10/29] add plane 3d datatype & component (no extensions, no python serialization) --- .../re_types/definitions/rerun/components.fbs | 1 + .../definitions/rerun/components/plane3d.fbs | 16 ++ .../re_types/definitions/rerun/datatypes.fbs | 1 + .../definitions/rerun/datatypes/plane3d.fbs | 20 ++ .../re_types/src/components/.gitattributes | 1 + crates/store/re_types/src/components/mod.rs | 2 + .../store/re_types/src/components/plane3d.rs | 120 ++++++++ .../re_types/src/datatypes/.gitattributes | 1 + crates/store/re_types/src/datatypes/mod.rs | 2 + .../store/re_types/src/datatypes/plane3d.rs | 256 ++++++++++++++++++ crates/viewer/re_viewer/src/reflection/mod.rs | 8 + docs/content/reference/types/components.md | 1 + .../reference/types/components/.gitattributes | 1 + .../reference/types/components/plane3d.md | 29 ++ docs/content/reference/types/datatypes.md | 1 + .../reference/types/datatypes/.gitattributes | 1 + .../reference/types/datatypes/plane3d.md | 29 ++ rerun_cpp/src/rerun/components.hpp | 1 + rerun_cpp/src/rerun/components/.gitattributes | 1 + rerun_cpp/src/rerun/components/plane3d.hpp | 73 +++++ rerun_cpp/src/rerun/datatypes.hpp | 1 + rerun_cpp/src/rerun/datatypes/.gitattributes | 2 + rerun_cpp/src/rerun/datatypes/plane3d.cpp | 64 +++++ rerun_cpp/src/rerun/datatypes/plane3d.hpp | 58 ++++ .../rerun_sdk/rerun/components/.gitattributes | 1 + .../rerun_sdk/rerun/components/__init__.py | 3 + .../rerun_sdk/rerun/components/plane3d.py | 41 +++ .../rerun_sdk/rerun/datatypes/.gitattributes | 1 + .../rerun_sdk/rerun/datatypes/__init__.py | 5 + rerun_py/rerun_sdk/rerun/datatypes/plane3d.py | 62 +++++ 30 files changed, 803 insertions(+) create mode 100644 crates/store/re_types/definitions/rerun/components/plane3d.fbs create mode 100644 crates/store/re_types/definitions/rerun/datatypes/plane3d.fbs create mode 100644 crates/store/re_types/src/components/plane3d.rs create mode 100644 crates/store/re_types/src/datatypes/plane3d.rs create mode 100644 docs/content/reference/types/components/plane3d.md create mode 100644 docs/content/reference/types/datatypes/plane3d.md create mode 100644 rerun_cpp/src/rerun/components/plane3d.hpp create mode 100644 rerun_cpp/src/rerun/datatypes/plane3d.cpp create mode 100644 rerun_cpp/src/rerun/datatypes/plane3d.hpp create mode 100644 rerun_py/rerun_sdk/rerun/components/plane3d.py create mode 100644 rerun_py/rerun_sdk/rerun/datatypes/plane3d.py diff --git a/crates/store/re_types/definitions/rerun/components.fbs b/crates/store/re_types/definitions/rerun/components.fbs index 57a3c7a1b851..4dc580313dc2 100644 --- a/crates/store/re_types/definitions/rerun/components.fbs +++ b/crates/store/re_types/definitions/rerun/components.fbs @@ -37,6 +37,7 @@ include "./components/media_type.fbs"; include "./components/name.fbs"; include "./components/opacity.fbs"; include "./components/pinhole_projection.fbs"; +include "./components/plane3d.fbs"; include "./components/position2d.fbs"; include "./components/position3d.fbs"; include "./components/radius.fbs"; diff --git a/crates/store/re_types/definitions/rerun/components/plane3d.fbs b/crates/store/re_types/definitions/rerun/components/plane3d.fbs new file mode 100644 index 000000000000..ba4fc22a3931 --- /dev/null +++ b/crates/store/re_types/definitions/rerun/components/plane3d.fbs @@ -0,0 +1,16 @@ +namespace rerun.components; + +/// An infinite 3D plane represented by a unit normal vector and a distance. +/// +/// Any point P on the plane fulfills the equation `dot(xyz, P) - d = 0`, where `xyz` is the plane's normal and `d` the distance. +/// This representation is also known as the Hesse normal form, see https://en.wikipedia.org/wiki/Hesse_normal_form +/// +/// Note: although the normal will be passed through to the +/// 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.rust.derive": "Default, Copy, PartialEq, bytemuck::Pod, bytemuck::Zeroable", + "attr.rust.repr": "transparent" +) { + xyzd: rerun.datatypes.Plane3D (order: 100); +} diff --git a/crates/store/re_types/definitions/rerun/datatypes.fbs b/crates/store/re_types/definitions/rerun/datatypes.fbs index c56691a867b2..5772f4c3b8d5 100644 --- a/crates/store/re_types/definitions/rerun/datatypes.fbs +++ b/crates/store/re_types/definitions/rerun/datatypes.fbs @@ -19,6 +19,7 @@ include "./datatypes/keypoint_pair.fbs"; include "./datatypes/mat3x3.fbs"; include "./datatypes/mat4x4.fbs"; include "./datatypes/pixel_format.fbs"; +include "./datatypes/plane3d.fbs"; include "./datatypes/quaternion.fbs"; include "./datatypes/range1d.fbs"; include "./datatypes/range2d.fbs"; diff --git a/crates/store/re_types/definitions/rerun/datatypes/plane3d.fbs b/crates/store/re_types/definitions/rerun/datatypes/plane3d.fbs new file mode 100644 index 000000000000..863a8ad1b911 --- /dev/null +++ b/crates/store/re_types/definitions/rerun/datatypes/plane3d.fbs @@ -0,0 +1,20 @@ +namespace rerun.datatypes; + +/// An infinite 3D plane represented by a unit normal vector and a distance. +/// +/// Any point P on the plane fulfills the equation `dot(xyz, P) - d = 0`, where `xyz` is the plane's normal and `d` the distance. +/// This representation is also known as the Hesse normal form, see https://en.wikipedia.org/wiki/Hesse_normal_form +/// +/// Note: although the normal will be passed through to the +/// 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.arrow.transparent", + "attr.python.array_aliases": "npt.NDArray[Any], npt.ArrayLike, Sequence[Sequence[float]]", + "attr.rust.derive": "Copy, PartialEq, PartialOrd, bytemuck::Pod, bytemuck::Zeroable", + "attr.rust.tuple_struct", + "attr.rust.repr": "C", + "attr.cpp.no_field_ctors" // Always be explicit about the values of the fields. +) { + xyzd: [float: 4] (order: 100); +} diff --git a/crates/store/re_types/src/components/.gitattributes b/crates/store/re_types/src/components/.gitattributes index f45278457d5c..3cf54dbb31cb 100644 --- a/crates/store/re_types/src/components/.gitattributes +++ b/crates/store/re_types/src/components/.gitattributes @@ -38,6 +38,7 @@ mod.rs linguist-generated=true name.rs linguist-generated=true opacity.rs linguist-generated=true pinhole_projection.rs linguist-generated=true +plane3d.rs linguist-generated=true pose_rotation_axis_angle.rs linguist-generated=true pose_rotation_quat.rs linguist-generated=true pose_scale3d.rs linguist-generated=true diff --git a/crates/store/re_types/src/components/mod.rs b/crates/store/re_types/src/components/mod.rs index 44993beca085..9208eeb9f0e4 100644 --- a/crates/store/re_types/src/components/mod.rs +++ b/crates/store/re_types/src/components/mod.rs @@ -62,6 +62,7 @@ mod opacity; mod opacity_ext; mod pinhole_projection; mod pinhole_projection_ext; +mod plane3d; mod pose_rotation_axis_angle; mod pose_rotation_axis_angle_ext; mod pose_rotation_quat; @@ -161,6 +162,7 @@ pub use self::media_type::MediaType; pub use self::name::Name; pub use self::opacity::Opacity; pub use self::pinhole_projection::PinholeProjection; +pub use self::plane3d::Plane3D; pub use self::pose_rotation_axis_angle::PoseRotationAxisAngle; pub use self::pose_rotation_quat::PoseRotationQuat; pub use self::pose_scale3d::PoseScale3D; diff --git a/crates/store/re_types/src/components/plane3d.rs b/crates/store/re_types/src/components/plane3d.rs new file mode 100644 index 000000000000..fa9ae2ccec49 --- /dev/null +++ b/crates/store/re_types/src/components/plane3d.rs @@ -0,0 +1,120 @@ +// 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/components/plane3d.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::ComponentName; +use ::re_types_core::SerializationResult; +use ::re_types_core::{ComponentBatch, MaybeOwnedComponentBatch}; +use ::re_types_core::{DeserializationError, DeserializationResult}; + +/// **Component**: An infinite 3D plane represented by a unit normal vector and a distance. +/// +/// Any point P on the plane fulfills the equation `dot(xyz, P) - d = 0`, where `xyz` is the plane's normal and `d` the distance. +/// This representation is also known as the Hesse normal form, see https://en.wikipedia.org/wiki/Hesse_normal_form +/// +/// Note: although the normal will be passed through to the +/// 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 +#[derive(Clone, Debug, Default, Copy, PartialEq, bytemuck::Pod, bytemuck::Zeroable)] +#[repr(transparent)] +pub struct Plane3D(pub crate::datatypes::Plane3D); + +impl ::re_types_core::SizeBytes for Plane3D { + #[inline] + fn heap_size_bytes(&self) -> u64 { + self.0.heap_size_bytes() + } + + #[inline] + fn is_pod() -> bool { + ::is_pod() + } +} + +impl> From for Plane3D { + fn from(v: T) -> Self { + Self(v.into()) + } +} + +impl std::borrow::Borrow for Plane3D { + #[inline] + fn borrow(&self) -> &crate::datatypes::Plane3D { + &self.0 + } +} + +impl std::ops::Deref for Plane3D { + type Target = crate::datatypes::Plane3D; + + #[inline] + fn deref(&self) -> &crate::datatypes::Plane3D { + &self.0 + } +} + +impl std::ops::DerefMut for Plane3D { + #[inline] + fn deref_mut(&mut self) -> &mut crate::datatypes::Plane3D { + &mut self.0 + } +} + +::re_types_core::macros::impl_into_cow!(Plane3D); + +impl ::re_types_core::Loggable for Plane3D { + #[inline] + fn arrow_datatype() -> arrow::datatypes::DataType { + crate::datatypes::Plane3D::arrow_datatype() + } + + fn to_arrow_opt<'a>( + data: impl IntoIterator>>>, + ) -> SerializationResult + where + Self: Clone + 'a, + { + crate::datatypes::Plane3D::to_arrow_opt(data.into_iter().map(|datum| { + datum.map(|datum| match datum.into() { + ::std::borrow::Cow::Borrowed(datum) => ::std::borrow::Cow::Borrowed(&datum.0), + ::std::borrow::Cow::Owned(datum) => ::std::borrow::Cow::Owned(datum.0), + }) + })) + } + + fn from_arrow2_opt( + arrow_data: &dyn arrow2::array::Array, + ) -> DeserializationResult>> + where + Self: Sized, + { + crate::datatypes::Plane3D::from_arrow2_opt(arrow_data) + .map(|v| v.into_iter().map(|v| v.map(Self)).collect()) + } + + #[inline] + fn from_arrow2(arrow_data: &dyn arrow2::array::Array) -> DeserializationResult> + where + Self: Sized, + { + crate::datatypes::Plane3D::from_arrow2(arrow_data).map(bytemuck::cast_vec) + } +} + +impl ::re_types_core::Component for Plane3D { + #[inline] + fn name() -> ComponentName { + "rerun.components.Plane3D".into() + } +} diff --git a/crates/store/re_types/src/datatypes/.gitattributes b/crates/store/re_types/src/datatypes/.gitattributes index 978b395e02a9..289cbd45793c 100644 --- a/crates/store/re_types/src/datatypes/.gitattributes +++ b/crates/store/re_types/src/datatypes/.gitattributes @@ -17,6 +17,7 @@ mat3x3.rs linguist-generated=true mat4x4.rs linguist-generated=true mod.rs linguist-generated=true pixel_format.rs linguist-generated=true +plane3d.rs linguist-generated=true quaternion.rs linguist-generated=true range1d.rs linguist-generated=true range2d.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 69cada396e56..900981b55636 100644 --- a/crates/store/re_types/src/datatypes/mod.rs +++ b/crates/store/re_types/src/datatypes/mod.rs @@ -30,6 +30,7 @@ mod mat4x4; mod mat4x4_ext; mod pixel_format; mod pixel_format_ext; +mod plane3d; mod quaternion; mod quaternion_ext; mod range1d; @@ -85,6 +86,7 @@ pub use self::keypoint_pair::KeypointPair; pub use self::mat3x3::Mat3x3; pub use self::mat4x4::Mat4x4; pub use self::pixel_format::PixelFormat; +pub use self::plane3d::Plane3D; pub use self::quaternion::Quaternion; pub use self::range1d::Range1D; pub use self::range2d::Range2D; diff --git a/crates/store/re_types/src/datatypes/plane3d.rs b/crates/store/re_types/src/datatypes/plane3d.rs new file mode 100644 index 000000000000..c55eed270a83 --- /dev/null +++ b/crates/store/re_types/src/datatypes/plane3d.rs @@ -0,0 +1,256 @@ +// 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/plane3d.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::ComponentName; +use ::re_types_core::SerializationResult; +use ::re_types_core::{ComponentBatch, MaybeOwnedComponentBatch}; +use ::re_types_core::{DeserializationError, DeserializationResult}; + +/// **Datatype**: An infinite 3D plane represented by a unit normal vector and a distance. +/// +/// Any point P on the plane fulfills the equation `dot(xyz, P) - d = 0`, where `xyz` is the plane's normal and `d` the distance. +/// This representation is also known as the Hesse normal form, see https://en.wikipedia.org/wiki/Hesse_normal_form +/// +/// Note: although the normal will be passed through to the +/// 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 +#[derive(Clone, Debug, Copy, PartialEq, PartialOrd, bytemuck::Pod, bytemuck::Zeroable)] +#[repr(C)] +pub struct Plane3D(pub [f32; 4usize]); + +impl ::re_types_core::SizeBytes for Plane3D { + #[inline] + fn heap_size_bytes(&self) -> u64 { + self.0.heap_size_bytes() + } + + #[inline] + fn is_pod() -> bool { + <[f32; 4usize]>::is_pod() + } +} + +impl From<[f32; 4usize]> for Plane3D { + #[inline] + fn from(xyzd: [f32; 4usize]) -> Self { + Self(xyzd) + } +} + +impl From for [f32; 4usize] { + #[inline] + fn from(value: Plane3D) -> Self { + value.0 + } +} + +::re_types_core::macros::impl_into_cow!(Plane3D); + +impl ::re_types_core::Loggable for Plane3D { + #[inline] + fn arrow_datatype() -> arrow::datatypes::DataType { + #![allow(clippy::wildcard_imports)] + use arrow::datatypes::*; + DataType::FixedSizeList( + std::sync::Arc::new(Field::new("item", DataType::Float32, false)), + 4, + ) + } + + 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::{Loggable as _, ResultExt as _}; + use arrow::{array::*, buffer::*, datatypes::*}; + + #[allow(unused)] + fn as_array_ref(t: T) -> ArrayRef { + std::sync::Arc::new(t) as ArrayRef + } + 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| datum.into_owned().0); + (datum.is_some(), datum) + }) + .unzip(); + let data0_validity: Option = { + let any_nones = somes.iter().any(|some| !*some); + any_nones.then(|| somes.into()) + }; + { + let data0_inner_data: Vec<_> = data0 + .into_iter() + .flat_map(|v| match v { + Some(v) => itertools::Either::Left(v.into_iter()), + None => itertools::Either::Right( + std::iter::repeat(Default::default()).take(4usize), + ), + }) + .collect(); + let data0_inner_validity: Option = + data0_validity.as_ref().map(|validity| { + validity + .iter() + .map(|b| std::iter::repeat(b).take(4usize)) + .flatten() + .collect::>() + .into() + }); + as_array_ref(FixedSizeListArray::new( + std::sync::Arc::new(Field::new("item", DataType::Float32, false)), + 4, + as_array_ref(PrimitiveArray::::new( + ScalarBuffer::from(data0_inner_data.into_iter().collect::>()), + data0_inner_validity, + )), + data0_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.Plane3D#xyzd")?; + if arrow_data.is_empty() { + Vec::new() + } else { + let offsets = (0..) + .step_by(4usize) + .zip((4usize..).step_by(4usize).take(arrow_data.len())); + let arrow_data_inner = { + let arrow_data_inner = &**arrow_data.values(); + arrow_data_inner + .as_any() + .downcast_ref::() + .ok_or_else(|| { + let expected = DataType::Float32; + let actual = arrow_data_inner.data_type().clone(); + DeserializationError::datatype_mismatch(expected, actual) + }) + .with_context("rerun.datatypes.Plane3D#xyzd")? + .into_iter() + .map(|opt| opt.copied()) + .collect::>() + }; + arrow2::bitmap::utils::ZipValidity::new_with_validity( + offsets, + arrow_data.validity(), + ) + .map(|elem| { + elem.map(|(start, end): (usize, usize)| { + debug_assert!(end - start == 4usize); + if end > 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.get_unchecked(start..end) }; + let data = data.iter().cloned().map(Option::unwrap_or_default); + + // NOTE: Unwrapping cannot fail: the length must be correct. + #[allow(clippy::unwrap_used)] + Ok(array_init::from_iter(data).unwrap()) + }) + .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.datatypes.Plane3D#xyzd") + .with_context("rerun.datatypes.Plane3D")?) + } + + #[inline] + fn from_arrow2(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::*}; + 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::Float32, false)), + 4, + ); + let actual = arrow_data.data_type().clone(); + DeserializationError::datatype_mismatch(expected, actual) + }) + .with_context("rerun.datatypes.Plane3D#xyzd")?; + let arrow_data_inner = &**arrow_data.values(); + bytemuck::cast_slice::<_, [_; 4usize]>( + arrow_data_inner + .as_any() + .downcast_ref::() + .ok_or_else(|| { + let expected = DataType::Float32; + let actual = arrow_data_inner.data_type().clone(); + DeserializationError::datatype_mismatch(expected, actual) + }) + .with_context("rerun.datatypes.Plane3D#xyzd")? + .values() + .as_slice(), + ) + }; + { + slice.iter().copied().map(Self).collect::>() + } + }) + } +} diff --git a/crates/viewer/re_viewer/src/reflection/mod.rs b/crates/viewer/re_viewer/src/reflection/mod.rs index ff67f7581250..bb9b81daea31 100644 --- a/crates/viewer/re_viewer/src/reflection/mod.rs +++ b/crates/viewer/re_viewer/src/reflection/mod.rs @@ -632,6 +632,14 @@ fn generate_component_reflection() -> Result::name(), + ComponentReflection { + docstring_md: "An infinite 3D plane represented by a unit normal vector and a distance.\n\nAny point P on the plane fulfills the equation `dot(xyz, P) - d = 0`, where `xyz` is the plane's normal and `d` the distance.\nThis representation is also known as the Hesse normal form, see https://en.wikipedia.org/wiki/Hesse_normal_form\n\nNote: although the normal will be passed through to the\ndatastore as provided, when used in the Viewer, planes will always be normalized.\nI.e. the plane with xyz = (2, 0, 0), d = 1 is equivalent to xyz = (1, 0, 0), d = 0.5", + custom_placeholder: Some(Plane3D::default().to_arrow2()?), + datatype: Plane3D::arrow2_datatype(), + }, + ), ( ::name(), ComponentReflection { diff --git a/docs/content/reference/types/components.md b/docs/content/reference/types/components.md index 84907d1b19b5..895232baec05 100644 --- a/docs/content/reference/types/components.md +++ b/docs/content/reference/types/components.md @@ -50,6 +50,7 @@ on [Entities and Components](../../concepts/entity-component.md). * [`Name`](components/name.md): A display name, typically for an entity or a item like a plot series. * [`Opacity`](components/opacity.md): Degree of transparency ranging from 0.0 (fully transparent) to 1.0 (fully opaque). * [`PinholeProjection`](components/pinhole_projection.md): Camera projection, from image coordinates to view coordinates. +* [`Plane3D`](components/plane3d.md): An infinite 3D plane represented by a unit normal vector and a distance. * [`PoseRotationAxisAngle`](components/pose_rotation_axis_angle.md): 3D rotation represented by a rotation around a given axis that doesn't propagate in the transform hierarchy. * [`PoseRotationQuat`](components/pose_rotation_quat.md): A 3D rotation expressed as a quaternion that doesn't propagate in the transform hierarchy. * [`PoseScale3D`](components/pose_scale3d.md): A 3D scale factor that doesn't propagate in the transform hierarchy. diff --git a/docs/content/reference/types/components/.gitattributes b/docs/content/reference/types/components/.gitattributes index 4cb988eea78b..ecb4df1c74f1 100644 --- a/docs/content/reference/types/components/.gitattributes +++ b/docs/content/reference/types/components/.gitattributes @@ -38,6 +38,7 @@ media_type.md linguist-generated=true name.md linguist-generated=true opacity.md linguist-generated=true pinhole_projection.md linguist-generated=true +plane3d.md linguist-generated=true pose_rotation_axis_angle.md linguist-generated=true pose_rotation_quat.md linguist-generated=true pose_scale3d.md linguist-generated=true diff --git a/docs/content/reference/types/components/plane3d.md b/docs/content/reference/types/components/plane3d.md new file mode 100644 index 000000000000..9a2388f5639b --- /dev/null +++ b/docs/content/reference/types/components/plane3d.md @@ -0,0 +1,29 @@ +--- +title: "Plane3D" +--- + + +An infinite 3D plane represented by a unit normal vector and a distance. + +Any point P on the plane fulfills the equation `dot(xyz, P) - d = 0`, where `xyz` is the plane's normal and `d` the distance. +This representation is also known as the Hesse normal form, see https://en.wikipedia.org/wiki/Hesse_normal_form + +Note: although the normal will be passed through to the +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 + +## Rerun datatype +[`Plane3D`](../datatypes/plane3d.md) + + +## Arrow datatype +``` +FixedSizeList<4, float32> +``` + +## API reference links + * 🌊 [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/datatypes.md b/docs/content/reference/types/datatypes.md index 653d0db2c963..750df8e173f8 100644 --- a/docs/content/reference/types/datatypes.md +++ b/docs/content/reference/types/datatypes.md @@ -26,6 +26,7 @@ Data types are the lowest layer of the data model hierarchy. They are re-usable * [`Mat3x3`](datatypes/mat3x3.md): A 3x3 Matrix. * [`Mat4x4`](datatypes/mat4x4.md): A 4x4 Matrix. * [`PixelFormat`](datatypes/pixel_format.md): Specifieds a particular format of an [`archetypes.Image`](https://rerun.io/docs/reference/types/archetypes/image). +* [`Plane3D`](datatypes/plane3d.md): An infinite 3D plane represented by a unit normal vector and a distance. * [`Quaternion`](datatypes/quaternion.md): A Quaternion represented by 4 real numbers. * [`Range1D`](datatypes/range1d.md): A 1D range, specifying a lower and upper bound. * [`Range2D`](datatypes/range2d.md): An Axis-Aligned Bounding Box in 2D space, implemented as the minimum and maximum corners. diff --git a/docs/content/reference/types/datatypes/.gitattributes b/docs/content/reference/types/datatypes/.gitattributes index 16fee72d8210..3454eebe12d8 100644 --- a/docs/content/reference/types/datatypes/.gitattributes +++ b/docs/content/reference/types/datatypes/.gitattributes @@ -20,6 +20,7 @@ keypoint_pair.md linguist-generated=true mat3x3.md linguist-generated=true mat4x4.md linguist-generated=true pixel_format.md linguist-generated=true +plane3d.md linguist-generated=true quaternion.md linguist-generated=true range1d.md linguist-generated=true range2d.md linguist-generated=true diff --git a/docs/content/reference/types/datatypes/plane3d.md b/docs/content/reference/types/datatypes/plane3d.md new file mode 100644 index 000000000000..45fb072ce74a --- /dev/null +++ b/docs/content/reference/types/datatypes/plane3d.md @@ -0,0 +1,29 @@ +--- +title: "Plane3D" +--- + + +An infinite 3D plane represented by a unit normal vector and a distance. + +Any point P on the plane fulfills the equation `dot(xyz, P) - d = 0`, where `xyz` is the plane's normal and `d` the distance. +This representation is also known as the Hesse normal form, see https://en.wikipedia.org/wiki/Hesse_normal_form + +Note: although the normal will be passed through to the +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 + + +## Arrow datatype +``` +FixedSizeList<4, float32> +``` + +## API reference links + * 🌊 [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) diff --git a/rerun_cpp/src/rerun/components.hpp b/rerun_cpp/src/rerun/components.hpp index 57eab0f62570..17ff34250df4 100644 --- a/rerun_cpp/src/rerun/components.hpp +++ b/rerun_cpp/src/rerun/components.hpp @@ -39,6 +39,7 @@ #include "components/name.hpp" #include "components/opacity.hpp" #include "components/pinhole_projection.hpp" +#include "components/plane3d.hpp" #include "components/pose_rotation_axis_angle.hpp" #include "components/pose_rotation_quat.hpp" #include "components/pose_scale3d.hpp" diff --git a/rerun_cpp/src/rerun/components/.gitattributes b/rerun_cpp/src/rerun/components/.gitattributes index 312f4f62e67b..57a1800528b7 100644 --- a/rerun_cpp/src/rerun/components/.gitattributes +++ b/rerun_cpp/src/rerun/components/.gitattributes @@ -48,6 +48,7 @@ media_type.hpp linguist-generated=true name.hpp linguist-generated=true opacity.hpp linguist-generated=true pinhole_projection.hpp linguist-generated=true +plane3d.hpp linguist-generated=true pose_rotation_axis_angle.hpp linguist-generated=true pose_rotation_quat.hpp linguist-generated=true pose_scale3d.hpp linguist-generated=true diff --git a/rerun_cpp/src/rerun/components/plane3d.hpp b/rerun_cpp/src/rerun/components/plane3d.hpp new file mode 100644 index 000000000000..fbc19a018484 --- /dev/null +++ b/rerun_cpp/src/rerun/components/plane3d.hpp @@ -0,0 +1,73 @@ +// 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/components/plane3d.fbs". + +#pragma once + +#include "../datatypes/plane3d.hpp" +#include "../result.hpp" + +#include +#include + +namespace rerun::components { + /// **Component**: An infinite 3D plane represented by a unit normal vector and a distance. + /// + /// Any point P on the plane fulfills the equation `dot(xyz, P) - d = 0`, where `xyz` is the plane's normal and `d` the distance. + /// This representation is also known as the Hesse normal form, see https://en.wikipedia.org/wiki/Hesse_normal_form + /// + /// Note: although the normal will be passed through to the + /// 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 { + rerun::datatypes::Plane3D xyzd; + + public: + Plane3D() = default; + + Plane3D(rerun::datatypes::Plane3D xyzd_) : xyzd(xyzd_) {} + + Plane3D& operator=(rerun::datatypes::Plane3D xyzd_) { + xyzd = xyzd_; + return *this; + } + + /// Cast to the underlying Plane3D datatype + operator rerun::datatypes::Plane3D() const { + return xyzd; + } + }; +} // namespace rerun::components + +namespace rerun { + static_assert(sizeof(rerun::datatypes::Plane3D) == sizeof(components::Plane3D)); + + /// \private + template <> + struct Loggable { + static constexpr const char Name[] = "rerun.components.Plane3D"; + + /// Returns the arrow data type this type corresponds to. + static const std::shared_ptr& arrow_datatype() { + return Loggable::arrow_datatype(); + } + + /// Serializes an array of `rerun::components::Plane3D` into an arrow array. + static Result> to_arrow( + const components::Plane3D* instances, size_t num_instances + ) { + if (num_instances == 0) { + return Loggable::to_arrow(nullptr, 0); + } else if (instances == nullptr) { + return rerun::Error( + ErrorCode::UnexpectedNullArgument, + "Passed array instances is null when num_elements> 0." + ); + } else { + return Loggable::to_arrow( + &instances->xyzd, + num_instances + ); + } + } + }; +} // namespace rerun diff --git a/rerun_cpp/src/rerun/datatypes.hpp b/rerun_cpp/src/rerun/datatypes.hpp index e18b3815ecec..0d41f3d62a23 100644 --- a/rerun_cpp/src/rerun/datatypes.hpp +++ b/rerun_cpp/src/rerun/datatypes.hpp @@ -21,6 +21,7 @@ #include "datatypes/mat3x3.hpp" #include "datatypes/mat4x4.hpp" #include "datatypes/pixel_format.hpp" +#include "datatypes/plane3d.hpp" #include "datatypes/quaternion.hpp" #include "datatypes/range1d.hpp" #include "datatypes/range2d.hpp" diff --git a/rerun_cpp/src/rerun/datatypes/.gitattributes b/rerun_cpp/src/rerun/datatypes/.gitattributes index fea5857aed33..46c43435cc8b 100644 --- a/rerun_cpp/src/rerun/datatypes/.gitattributes +++ b/rerun_cpp/src/rerun/datatypes/.gitattributes @@ -39,6 +39,8 @@ mat4x4.cpp linguist-generated=true mat4x4.hpp linguist-generated=true pixel_format.cpp linguist-generated=true pixel_format.hpp linguist-generated=true +plane3d.cpp linguist-generated=true +plane3d.hpp linguist-generated=true quaternion.cpp linguist-generated=true quaternion.hpp linguist-generated=true range1d.cpp linguist-generated=true diff --git a/rerun_cpp/src/rerun/datatypes/plane3d.cpp b/rerun_cpp/src/rerun/datatypes/plane3d.cpp new file mode 100644 index 000000000000..659c98f13e00 --- /dev/null +++ b/rerun_cpp/src/rerun/datatypes/plane3d.cpp @@ -0,0 +1,64 @@ +// 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/plane3d.fbs". + +#include "plane3d.hpp" + +#include +#include + +namespace rerun::datatypes {} + +namespace rerun { + const std::shared_ptr& Loggable::arrow_datatype() { + static const auto datatype = + arrow::fixed_size_list(arrow::field("item", arrow::float32(), false), 4); + return datatype; + } + + Result> Loggable::to_arrow( + const datatypes::Plane3D* 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::FixedSizeListBuilder* builder, const datatypes::Plane3D* 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->AppendValues(static_cast(num_elements))); + static_assert(sizeof(elements[0].xyzd) == sizeof(elements[0])); + ARROW_RETURN_NOT_OK(value_builder->AppendValues( + elements[0].xyzd.data(), + static_cast(num_elements * 4), + nullptr + )); + + return Error::ok(); + } +} // namespace rerun diff --git a/rerun_cpp/src/rerun/datatypes/plane3d.hpp b/rerun_cpp/src/rerun/datatypes/plane3d.hpp new file mode 100644 index 000000000000..5d66df54a923 --- /dev/null +++ b/rerun_cpp/src/rerun/datatypes/plane3d.hpp @@ -0,0 +1,58 @@ +// 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/plane3d.fbs". + +#pragma once + +#include "../result.hpp" + +#include +#include +#include + +namespace arrow { + class Array; + class DataType; + class FixedSizeListBuilder; +} // namespace arrow + +namespace rerun::datatypes { + /// **Datatype**: An infinite 3D plane represented by a unit normal vector and a distance. + /// + /// Any point P on the plane fulfills the equation `dot(xyz, P) - d = 0`, where `xyz` is the plane's normal and `d` the distance. + /// This representation is also known as the Hesse normal form, see https://en.wikipedia.org/wiki/Hesse_normal_form + /// + /// Note: although the normal will be passed through to the + /// 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 { + std::array xyzd; + + public: + Plane3D() = default; + }; +} // namespace rerun::datatypes + +namespace rerun { + template + struct Loggable; + + /// \private + template <> + struct Loggable { + static constexpr const char Name[] = "rerun.datatypes.Plane3D"; + + /// Returns the arrow data type this type corresponds to. + static const std::shared_ptr& arrow_datatype(); + + /// Serializes an array of `rerun::datatypes::Plane3D` into an arrow array. + static Result> to_arrow( + const datatypes::Plane3D* instances, size_t num_instances + ); + + /// Fills an arrow array builder with an array of this type. + static rerun::Error fill_arrow_array_builder( + arrow::FixedSizeListBuilder* builder, const datatypes::Plane3D* elements, + size_t num_elements + ); + }; +} // namespace rerun diff --git a/rerun_py/rerun_sdk/rerun/components/.gitattributes b/rerun_py/rerun_sdk/rerun/components/.gitattributes index d9db90a272aa..bc78f211dc27 100644 --- a/rerun_py/rerun_sdk/rerun/components/.gitattributes +++ b/rerun_py/rerun_sdk/rerun/components/.gitattributes @@ -39,6 +39,7 @@ media_type.py linguist-generated=true name.py linguist-generated=true opacity.py linguist-generated=true pinhole_projection.py linguist-generated=true +plane3d.py linguist-generated=true pose_rotation_axis_angle.py linguist-generated=true pose_rotation_quat.py linguist-generated=true pose_scale3d.py linguist-generated=true diff --git a/rerun_py/rerun_sdk/rerun/components/__init__.py b/rerun_py/rerun_sdk/rerun/components/__init__.py index 0b3141a8eb38..1bc230a70e79 100644 --- a/rerun_py/rerun_sdk/rerun/components/__init__.py +++ b/rerun_py/rerun_sdk/rerun/components/__init__.py @@ -54,6 +54,7 @@ from .name import Name, NameBatch from .opacity import Opacity, OpacityBatch from .pinhole_projection import PinholeProjection, PinholeProjectionBatch +from .plane3d import Plane3D, Plane3DBatch from .pose_rotation_axis_angle import PoseRotationAxisAngle, PoseRotationAxisAngleBatch from .pose_rotation_quat import PoseRotationQuat, PoseRotationQuatBatch from .pose_scale3d import PoseScale3D, PoseScale3DBatch @@ -188,6 +189,8 @@ "OpacityBatch", "PinholeProjection", "PinholeProjectionBatch", + "Plane3D", + "Plane3DBatch", "PoseRotationAxisAngle", "PoseRotationAxisAngleBatch", "PoseRotationQuat", diff --git a/rerun_py/rerun_sdk/rerun/components/plane3d.py b/rerun_py/rerun_sdk/rerun/components/plane3d.py new file mode 100644 index 000000000000..56699ca3186f --- /dev/null +++ b/rerun_py/rerun_sdk/rerun/components/plane3d.py @@ -0,0 +1,41 @@ +# 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/components/plane3d.fbs". + +# You can extend this class by creating a "Plane3DExt" class in "plane3d_ext.py". + +from __future__ import annotations + +from .. import datatypes +from .._baseclasses import ( + ComponentBatchMixin, + ComponentMixin, +) + +__all__ = ["Plane3D", "Plane3DBatch"] + + +class Plane3D(datatypes.Plane3D, ComponentMixin): + """ + **Component**: An infinite 3D plane represented by a unit normal vector and a distance. + + Any point P on the plane fulfills the equation `dot(xyz, P) - d = 0`, where `xyz` is the plane's normal and `d` the distance. + This representation is also known as the Hesse normal form, see https://en.wikipedia.org/wiki/Hesse_normal_form + + Note: although the normal will be passed through to the + 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 + """ + + _BATCH_TYPE = None + # You can define your own __init__ function as a member of Plane3DExt in plane3d_ext.py + + # Note: there are no fields here because Plane3D delegates to datatypes.Plane3D + pass + + +class Plane3DBatch(datatypes.Plane3DBatch, ComponentBatchMixin): + _COMPONENT_NAME: str = "rerun.components.Plane3D" + + +# This is patched in late to avoid circular dependencies. +Plane3D._BATCH_TYPE = Plane3DBatch # type: ignore[assignment] diff --git a/rerun_py/rerun_sdk/rerun/datatypes/.gitattributes b/rerun_py/rerun_sdk/rerun/datatypes/.gitattributes index 988472fc7b8a..dcfe4dfeec99 100644 --- a/rerun_py/rerun_sdk/rerun/datatypes/.gitattributes +++ b/rerun_py/rerun_sdk/rerun/datatypes/.gitattributes @@ -21,6 +21,7 @@ keypoint_pair.py linguist-generated=true mat3x3.py linguist-generated=true mat4x4.py linguist-generated=true pixel_format.py linguist-generated=true +plane3d.py linguist-generated=true quaternion.py linguist-generated=true range1d.py linguist-generated=true range2d.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 9a6dfb584c78..1cf1156f07c8 100644 --- a/rerun_py/rerun_sdk/rerun/datatypes/__init__.py +++ b/rerun_py/rerun_sdk/rerun/datatypes/__init__.py @@ -26,6 +26,7 @@ from .mat3x3 import Mat3x3, Mat3x3ArrayLike, Mat3x3Batch, Mat3x3Like from .mat4x4 import Mat4x4, Mat4x4ArrayLike, Mat4x4Batch, Mat4x4Like from .pixel_format import PixelFormat, PixelFormatArrayLike, PixelFormatBatch, PixelFormatLike +from .plane3d import Plane3D, Plane3DArrayLike, Plane3DBatch, Plane3DLike from .quaternion import Quaternion, QuaternionArrayLike, QuaternionBatch, QuaternionLike from .range1d import Range1D, Range1DArrayLike, Range1DBatch, Range1DLike from .range2d import Range2D, Range2DArrayLike, Range2DBatch, Range2DLike @@ -152,6 +153,10 @@ "PixelFormatArrayLike", "PixelFormatBatch", "PixelFormatLike", + "Plane3D", + "Plane3DArrayLike", + "Plane3DBatch", + "Plane3DLike", "Quaternion", "QuaternionArrayLike", "QuaternionBatch", diff --git a/rerun_py/rerun_sdk/rerun/datatypes/plane3d.py b/rerun_py/rerun_sdk/rerun/datatypes/plane3d.py new file mode 100644 index 000000000000..c81819123838 --- /dev/null +++ b/rerun_py/rerun_sdk/rerun/datatypes/plane3d.py @@ -0,0 +1,62 @@ +# 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/plane3d.fbs". + +# You can extend this class by creating a "Plane3DExt" class in "plane3d_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, +) +from .._converters import ( + to_np_float32, +) + +__all__ = ["Plane3D", "Plane3DArrayLike", "Plane3DBatch", "Plane3DLike"] + + +@define(init=False) +class Plane3D: + """ + **Datatype**: An infinite 3D plane represented by a unit normal vector and a distance. + + Any point P on the plane fulfills the equation `dot(xyz, P) - d = 0`, where `xyz` is the plane's normal and `d` the distance. + This representation is also known as the Hesse normal form, see https://en.wikipedia.org/wiki/Hesse_normal_form + + Note: although the normal will be passed through to the + 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 + """ + + def __init__(self: Any, xyzd: Plane3DLike): + """Create a new instance of the Plane3D datatype.""" + + # You can define your own __init__ function as a member of Plane3DExt in plane3d_ext.py + self.__attrs_init__(xyzd=xyzd) + + xyzd: npt.NDArray[np.float32] = field(converter=to_np_float32) + + def __array__(self, dtype: npt.DTypeLike = None) -> npt.NDArray[Any]: + # You can define your own __array__ function as a member of Plane3DExt in plane3d_ext.py + return np.asarray(self.xyzd, dtype=dtype) + + +Plane3DLike = Plane3D +Plane3DArrayLike = Union[Plane3D, Sequence[Plane3DLike], npt.NDArray[Any], npt.ArrayLike, Sequence[Sequence[float]]] + + +class Plane3DBatch(BaseBatch[Plane3DArrayLike]): + _ARROW_DATATYPE = pa.list_(pa.field("item", pa.float32(), nullable=False, metadata={}), 4) + + @staticmethod + def _native_to_pa_array(data: Plane3DArrayLike, data_type: pa.DataType) -> pa.Array: + raise NotImplementedError( + "Arrow serialization of Plane3D not implemented: We lack codegen for arrow-serialization of general structs" + ) # You need to implement native_to_pa_array_override in plane3d_ext.py From c12484fc61a1e01bee1d1b2ae857b6f459f88b35 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Tue, 3 Dec 2024 11:55:19 +0100 Subject: [PATCH 11/29] remove plane offset & orientation again, add Rust extensions to Plane3D --- Cargo.lock | 1 + crates/store/re_types/Cargo.toml | 5 +- .../blueprint/archetypes/line_grid_3d.fbs | 9 +- .../rerun/blueprint/components.fbs | 2 - .../blueprint/components/plane_offset.fbs | 12 -- .../components/plane_orientation.fbs | 18 -- .../definitions/rerun/components/plane3d.fbs | 2 +- .../src/blueprint/archetypes/line_grid3d.rs | 79 +++------ .../src/blueprint/components/.gitattributes | 2 - .../re_types/src/blueprint/components/mod.rs | 4 - .../src/blueprint/components/plane_offset.rs | 116 ------------ .../blueprint/components/plane_orientation.rs | 167 ------------------ crates/store/re_types/src/components/mod.rs | 1 + .../store/re_types/src/components/plane3d.rs | 2 +- .../re_types/src/components/plane3d_ext.rs | 31 ++++ crates/store/re_types/src/datatypes/mod.rs | 1 + .../re_types/src/datatypes/plane3d_ext.rs | 50 ++++++ crates/viewer/re_component_ui/src/lib.rs | 8 +- .../viewer/re_space_view_spatial/src/ui_3d.rs | 14 +- .../src/view_3d_properties.rs | 22 +-- .../src/blueprint/validation_gen/mod.rs | 4 - crates/viewer/re_viewer/src/reflection/mod.rs | 27 +-- .../reference/types/views/spatial3d_view.md | 3 +- .../blueprint/archetypes/line_grid3d.cpp | 11 +- .../blueprint/archetypes/line_grid3d.hpp | 28 +-- rerun_cpp/src/rerun/blueprint/components.hpp | 2 - .../rerun/blueprint/components/.gitattributes | 3 - .../blueprint/components/plane_offset.hpp | 74 -------- .../components/plane_orientation.cpp | 61 ------- .../components/plane_orientation.hpp | 60 ------- .../rerun/blueprint/archetypes/line_grid3d.py | 40 ++--- .../rerun/blueprint/components/.gitattributes | 2 - .../rerun/blueprint/components/__init__.py | 8 - .../blueprint/components/plane_offset.py | 32 ---- .../blueprint/components/plane_orientation.py | 71 -------- 35 files changed, 159 insertions(+), 813 deletions(-) delete mode 100644 crates/store/re_types/definitions/rerun/blueprint/components/plane_offset.fbs delete mode 100644 crates/store/re_types/definitions/rerun/blueprint/components/plane_orientation.fbs delete mode 100644 crates/store/re_types/src/blueprint/components/plane_offset.rs delete mode 100644 crates/store/re_types/src/blueprint/components/plane_orientation.rs create mode 100644 crates/store/re_types/src/components/plane3d_ext.rs create mode 100644 crates/store/re_types/src/datatypes/plane3d_ext.rs delete mode 100644 rerun_cpp/src/rerun/blueprint/components/plane_offset.hpp delete mode 100644 rerun_cpp/src/rerun/blueprint/components/plane_orientation.cpp delete mode 100644 rerun_cpp/src/rerun/blueprint/components/plane_orientation.hpp delete mode 100644 rerun_py/rerun_sdk/rerun/blueprint/components/plane_offset.py delete mode 100644 rerun_py/rerun_sdk/rerun/blueprint/components/plane_orientation.py diff --git a/Cargo.lock b/Cargo.lock index a5d7e947a821..09a26e1043a1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6498,6 +6498,7 @@ dependencies = [ "re_format", "re_log", "re_log_types", + "re_math", "re_tracing", "re_types_builder", "re_types_core", diff --git a/crates/store/re_types/Cargo.toml b/crates/store/re_types/Cargo.toml index 94caec927202..46a740e3d6b6 100644 --- a/crates/store/re_types/Cargo.toml +++ b/crates/store/re_types/Cargo.toml @@ -33,8 +33,8 @@ ecolor = ["dep:ecolor"] ## Enable conversions to plot primitives egui_plot = ["dep:egui_plot"] -## Add support for some math operations using [`glam`](https://crates.io/crates/glam/). -glam = ["dep:glam"] +## Add support for some math operations using [`glam`](https://crates.io/crates/glam/) and [`re_math`](https://crates.io/crates/re_math/). +glam = ["dep:glam", "dep:re_math"] ## Integration with the [`image`](https://crates.io/crates/image/) crate, plus JPEG support. image = ["dep:ecolor", "dep:image"] @@ -92,6 +92,7 @@ image = { workspace = true, optional = true, default-features = false, features "jpeg", ] } mint = { workspace = true, optional = true } +re_math = { workspace = true, optional = true } serde = { workspace = true, optional = true, features = ["derive", "rc"] } diff --git a/crates/store/re_types/definitions/rerun/blueprint/archetypes/line_grid_3d.fbs b/crates/store/re_types/definitions/rerun/blueprint/archetypes/line_grid_3d.fbs index e5052922c5e0..e1d1094056da 100644 --- a/crates/store/re_types/definitions/rerun/blueprint/archetypes/line_grid_3d.fbs +++ b/crates/store/re_types/definitions/rerun/blueprint/archetypes/line_grid_3d.fbs @@ -12,13 +12,10 @@ table LineGrid3D ( /// Space between grid lines spacing of one line to the next in scene units. spacing: rerun.blueprint.components.GridSpacing ("attr.rerun.component_optional", nullable, order: 2000); - /// How the grid is oriented. + /// In what plane the grid is drawn. /// - /// Defaults to whatever plane is determined as the down plane by view coordinates if present. - orientation: rerun.blueprint.components.PlaneOrientation ("attr.rerun.component_optional", nullable, order: 3000); - - /// Offset of the grid along its normal. - offset: rerun.blueprint.components.PlaneOffset ("attr.rerun.component_optional", nullable, order: 4000); + /// Defaults to whatever plane is determined as the plane at zero units up/down as defined by [`archetype.ViewCoordinates`] if present. + plane: rerun.components.Plane3D ("attr.rerun.component_optional", nullable, order: 3000); /// How thick the lines should be in ui units. /// diff --git a/crates/store/re_types/definitions/rerun/blueprint/components.fbs b/crates/store/re_types/definitions/rerun/blueprint/components.fbs index 2b049eaaf4c8..46c186e893e5 100644 --- a/crates/store/re_types/definitions/rerun/blueprint/components.fbs +++ b/crates/store/re_types/definitions/rerun/blueprint/components.fbs @@ -18,8 +18,6 @@ include "./components/interactive.fbs"; include "./components/lock_range_during_zoom.fbs"; include "./components/map_provider.fbs"; include "./components/panel_state.fbs"; -include "./components/plane_offset.fbs"; -include "./components/plane_orientation.fbs"; include "./components/query_expression.fbs"; include "./components/root_container.fbs"; include "./components/row_share.fbs"; diff --git a/crates/store/re_types/definitions/rerun/blueprint/components/plane_offset.fbs b/crates/store/re_types/definitions/rerun/blueprint/components/plane_offset.fbs deleted file mode 100644 index 9a6b3008b8b1..000000000000 --- a/crates/store/re_types/definitions/rerun/blueprint/components/plane_offset.fbs +++ /dev/null @@ -1,12 +0,0 @@ -namespace rerun.blueprint.components; - -/// Offset of a plane along its normal in scene units. -table PlaneOffset ( - "attr.python.aliases": "float", - "attr.python.array_aliases": "npt.ArrayLike", - "attr.rust.derive": "Default", - "attr.rerun.scope": "blueprint" -) { - /// Offset of a plane along its normal in scene units. - distance: rerun.datatypes.Float32 (order: 100); -} diff --git a/crates/store/re_types/definitions/rerun/blueprint/components/plane_orientation.fbs b/crates/store/re_types/definitions/rerun/blueprint/components/plane_orientation.fbs deleted file mode 100644 index b4a44b97e309..000000000000 --- a/crates/store/re_types/definitions/rerun/blueprint/components/plane_orientation.fbs +++ /dev/null @@ -1,18 +0,0 @@ -namespace rerun.blueprint.components; - -/// Orientation of a 3D axis aligned plane. -enum PlaneOrientation: ubyte ( - "attr.rerun.scope": "blueprint" -) { - /// Invalid value. Won't show up in generated types. - Invalid = 0, - - /// Plane spanned by X and Z axis. - Xz, - - /// Plane spanned by Y and Z axis. - Yz, - - /// Plane spanned by X and Y axis. - Xy (default), // we default to RFU cameras in the view. -} diff --git a/crates/store/re_types/definitions/rerun/components/plane3d.fbs b/crates/store/re_types/definitions/rerun/components/plane3d.fbs index ba4fc22a3931..c5b61526d719 100644 --- a/crates/store/re_types/definitions/rerun/components/plane3d.fbs +++ b/crates/store/re_types/definitions/rerun/components/plane3d.fbs @@ -9,7 +9,7 @@ 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.rust.derive": "Default, Copy, PartialEq, bytemuck::Pod, bytemuck::Zeroable", + "attr.rust.derive": "Copy, PartialEq, bytemuck::Pod, bytemuck::Zeroable", "attr.rust.repr": "transparent" ) { xyzd: rerun.datatypes.Plane3D (order: 100); diff --git a/crates/store/re_types/src/blueprint/archetypes/line_grid3d.rs b/crates/store/re_types/src/blueprint/archetypes/line_grid3d.rs index 9bfb3371c86d..1ddec38f1f9d 100644 --- a/crates/store/re_types/src/blueprint/archetypes/line_grid3d.rs +++ b/crates/store/re_types/src/blueprint/archetypes/line_grid3d.rs @@ -29,13 +29,10 @@ pub struct LineGrid3D { /// Space between grid lines spacing of one line to the next in scene units. pub spacing: Option, - /// How the grid is oriented. + /// In what plane the grid is drawn. /// - /// Defaults to whatever plane is determined as the down plane by view coordinates if present. - pub orientation: Option, - - /// Offset of the grid along its normal. - pub offset: Option, + /// Defaults to whatever plane is determined as the plane at zero units up/down as defined by [`archetype.ViewCoordinates`] if present. + pub plane: Option, /// How thick the lines should be in ui units. /// @@ -54,8 +51,7 @@ impl ::re_types_core::SizeBytes for LineGrid3D { fn heap_size_bytes(&self) -> u64 { self.visible.heap_size_bytes() + self.spacing.heap_size_bytes() - + self.orientation.heap_size_bytes() - + self.offset.heap_size_bytes() + + self.plane.heap_size_bytes() + self.line_radius.heap_size_bytes() + self.color.heap_size_bytes() } @@ -64,8 +60,7 @@ impl ::re_types_core::SizeBytes for LineGrid3D { fn is_pod() -> bool { >::is_pod() && >::is_pod() - && >::is_pod() - && >::is_pod() + && >::is_pod() && >::is_pod() && >::is_pod() } @@ -77,34 +72,32 @@ static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentName; 0usize]> = static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentName; 1usize]> = once_cell::sync::Lazy::new(|| ["rerun.blueprint.components.LineGrid3DIndicator".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.Visible".into(), "rerun.blueprint.components.GridSpacing".into(), - "rerun.blueprint.components.PlaneOrientation".into(), - "rerun.blueprint.components.PlaneOffset".into(), + "rerun.components.Plane3D".into(), "rerun.blueprint.components.UiRadius".into(), "rerun.components.Color".into(), ] }); -static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentName; 7usize]> = +static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentName; 6usize]> = once_cell::sync::Lazy::new(|| { [ "rerun.blueprint.components.LineGrid3DIndicator".into(), "rerun.blueprint.components.Visible".into(), "rerun.blueprint.components.GridSpacing".into(), - "rerun.blueprint.components.PlaneOrientation".into(), - "rerun.blueprint.components.PlaneOffset".into(), + "rerun.components.Plane3D".into(), "rerun.blueprint.components.UiRadius".into(), "rerun.components.Color".into(), ] }); impl LineGrid3D { - /// The total number of components in the archetype: 0 required, 1 recommended, 6 optional - pub const NUM_COMPONENTS: usize = 7usize; + /// The total number of components in the archetype: 0 required, 1 recommended, 5 optional + pub const NUM_COMPONENTS: usize = 6usize; } /// Indicator component for the [`LineGrid3D`] [`::re_types_core::Archetype`] @@ -179,27 +172,15 @@ impl ::re_types_core::Archetype for LineGrid3D { } else { None }; - let orientation = if let Some(array) = - arrays_by_name.get("rerun.blueprint.components.PlaneOrientation") - { - ::from_arrow2_opt(&**array) - .with_context("rerun.blueprint.archetypes.LineGrid3D#orientation")? + let plane = if let Some(array) = arrays_by_name.get("rerun.components.Plane3D") { + ::from_arrow2_opt(&**array) + .with_context("rerun.blueprint.archetypes.LineGrid3D#plane")? .into_iter() .next() .flatten() } else { None }; - let offset = - if let Some(array) = arrays_by_name.get("rerun.blueprint.components.PlaneOffset") { - ::from_arrow2_opt(&**array) - .with_context("rerun.blueprint.archetypes.LineGrid3D#offset")? - .into_iter() - .next() - .flatten() - } else { - None - }; let line_radius = if let Some(array) = arrays_by_name.get("rerun.blueprint.components.UiRadius") { ::from_arrow2_opt(&**array) @@ -222,8 +203,7 @@ impl ::re_types_core::Archetype for LineGrid3D { Ok(Self { visible, spacing, - orientation, - offset, + plane, line_radius, color, }) @@ -242,10 +222,7 @@ impl ::re_types_core::AsComponents for LineGrid3D { self.spacing .as_ref() .map(|comp| (comp as &dyn ComponentBatch).into()), - self.orientation - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch).into()), - self.offset + self.plane .as_ref() .map(|comp| (comp as &dyn ComponentBatch).into()), self.line_radius @@ -270,8 +247,7 @@ impl LineGrid3D { Self { visible: None, spacing: None, - orientation: None, - offset: None, + plane: None, line_radius: None, color: None, } @@ -299,25 +275,12 @@ impl LineGrid3D { self } - /// How the grid is oriented. + /// In what plane the grid is drawn. /// - /// Defaults to whatever plane is determined as the down plane by view coordinates if present. + /// Defaults to whatever plane is determined as the plane at zero units up/down as defined by [`archetype.ViewCoordinates`] if present. #[inline] - pub fn with_orientation( - mut self, - orientation: impl Into, - ) -> Self { - self.orientation = Some(orientation.into()); - self - } - - /// Offset of the grid along its normal. - #[inline] - pub fn with_offset( - mut self, - offset: impl Into, - ) -> Self { - self.offset = Some(offset.into()); + pub fn with_plane(mut self, plane: impl Into) -> Self { + self.plane = Some(plane.into()); self } diff --git a/crates/store/re_types/src/blueprint/components/.gitattributes b/crates/store/re_types/src/blueprint/components/.gitattributes index 4ac1300d4535..d57e8c893983 100644 --- a/crates/store/re_types/src/blueprint/components/.gitattributes +++ b/crates/store/re_types/src/blueprint/components/.gitattributes @@ -16,8 +16,6 @@ lock_range_during_zoom.rs linguist-generated=true map_provider.rs linguist-generated=true mod.rs linguist-generated=true panel_state.rs linguist-generated=true -plane_offset.rs linguist-generated=true -plane_orientation.rs linguist-generated=true query_expression.rs linguist-generated=true row_share.rs linguist-generated=true selected_columns.rs linguist-generated=true diff --git a/crates/store/re_types/src/blueprint/components/mod.rs b/crates/store/re_types/src/blueprint/components/mod.rs index cc8a1bd5c387..d564f791a1e5 100644 --- a/crates/store/re_types/src/blueprint/components/mod.rs +++ b/crates/store/re_types/src/blueprint/components/mod.rs @@ -21,8 +21,6 @@ mod lock_range_during_zoom; mod map_provider; mod panel_state; mod panel_state_ext; -mod plane_offset; -mod plane_orientation; mod query_expression; mod row_share; mod selected_columns; @@ -59,8 +57,6 @@ pub use self::interactive::Interactive; pub use self::lock_range_during_zoom::LockRangeDuringZoom; pub use self::map_provider::MapProvider; pub use self::panel_state::PanelState; -pub use self::plane_offset::PlaneOffset; -pub use self::plane_orientation::PlaneOrientation; pub use self::query_expression::QueryExpression; pub use self::row_share::RowShare; pub use self::selected_columns::SelectedColumns; diff --git a/crates/store/re_types/src/blueprint/components/plane_offset.rs b/crates/store/re_types/src/blueprint/components/plane_offset.rs deleted file mode 100644 index 3a1fd0170e8d..000000000000 --- a/crates/store/re_types/src/blueprint/components/plane_offset.rs +++ /dev/null @@ -1,116 +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/blueprint/components/plane_offset.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::ComponentName; -use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, MaybeOwnedComponentBatch}; -use ::re_types_core::{DeserializationError, DeserializationResult}; - -/// **Component**: Offset of a plane along its normal in scene units. -#[derive(Clone, Debug, Default)] -pub struct PlaneOffset( - /// Offset of a plane along its normal in scene units. - pub crate::datatypes::Float32, -); - -impl ::re_types_core::SizeBytes for PlaneOffset { - #[inline] - fn heap_size_bytes(&self) -> u64 { - self.0.heap_size_bytes() - } - - #[inline] - fn is_pod() -> bool { - ::is_pod() - } -} - -impl> From for PlaneOffset { - fn from(v: T) -> Self { - Self(v.into()) - } -} - -impl std::borrow::Borrow for PlaneOffset { - #[inline] - fn borrow(&self) -> &crate::datatypes::Float32 { - &self.0 - } -} - -impl std::ops::Deref for PlaneOffset { - type Target = crate::datatypes::Float32; - - #[inline] - fn deref(&self) -> &crate::datatypes::Float32 { - &self.0 - } -} - -impl std::ops::DerefMut for PlaneOffset { - #[inline] - fn deref_mut(&mut self) -> &mut crate::datatypes::Float32 { - &mut self.0 - } -} - -::re_types_core::macros::impl_into_cow!(PlaneOffset); - -impl ::re_types_core::Loggable for PlaneOffset { - #[inline] - fn arrow_datatype() -> arrow::datatypes::DataType { - crate::datatypes::Float32::arrow_datatype() - } - - fn to_arrow_opt<'a>( - data: impl IntoIterator>>>, - ) -> SerializationResult - where - Self: Clone + 'a, - { - crate::datatypes::Float32::to_arrow_opt(data.into_iter().map(|datum| { - datum.map(|datum| match datum.into() { - ::std::borrow::Cow::Borrowed(datum) => ::std::borrow::Cow::Borrowed(&datum.0), - ::std::borrow::Cow::Owned(datum) => ::std::borrow::Cow::Owned(datum.0), - }) - })) - } - - fn from_arrow2_opt( - arrow_data: &dyn arrow2::array::Array, - ) -> DeserializationResult>> - where - Self: Sized, - { - crate::datatypes::Float32::from_arrow2_opt(arrow_data) - .map(|v| v.into_iter().map(|v| v.map(Self)).collect()) - } - - #[inline] - fn from_arrow2(arrow_data: &dyn arrow2::array::Array) -> DeserializationResult> - where - Self: Sized, - { - crate::datatypes::Float32::from_arrow2(arrow_data) - .map(|v| v.into_iter().map(Self).collect()) - } -} - -impl ::re_types_core::Component for PlaneOffset { - #[inline] - fn name() -> ComponentName { - "rerun.blueprint.components.PlaneOffset".into() - } -} diff --git a/crates/store/re_types/src/blueprint/components/plane_orientation.rs b/crates/store/re_types/src/blueprint/components/plane_orientation.rs deleted file mode 100644 index 970aa3310487..000000000000 --- a/crates/store/re_types/src/blueprint/components/plane_orientation.rs +++ /dev/null @@ -1,167 +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/blueprint/components/plane_orientation.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)] -#![allow(non_camel_case_types)] - -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**: Orientation of a 3D axis aligned plane. -#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Default)] -#[repr(u8)] -pub enum PlaneOrientation { - /// Plane spanned by X and Z axis. - Xz = 1, - - /// Plane spanned by Y and Z axis. - Yz = 2, - - /// Plane spanned by X and Y axis. - #[default] - Xy = 3, -} - -impl ::re_types_core::reflection::Enum for PlaneOrientation { - #[inline] - fn variants() -> &'static [Self] { - &[Self::Xz, Self::Yz, Self::Xy] - } - - #[inline] - fn docstring_md(self) -> &'static str { - match self { - Self::Xz => "Plane spanned by X and Z axis.", - Self::Yz => "Plane spanned by Y and Z axis.", - Self::Xy => "Plane spanned by X and Y axis.", - } - } -} - -impl ::re_types_core::SizeBytes for PlaneOrientation { - #[inline] - fn heap_size_bytes(&self) -> u64 { - 0 - } - - #[inline] - fn is_pod() -> bool { - true - } -} - -impl std::fmt::Display for PlaneOrientation { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - Self::Xz => write!(f, "Xz"), - Self::Yz => write!(f, "Yz"), - Self::Xy => write!(f, "Xy"), - } - } -} - -::re_types_core::macros::impl_into_cow!(PlaneOrientation); - -impl ::re_types_core::Loggable for PlaneOrientation { - #[inline] - fn arrow_datatype() -> arrow::datatypes::DataType { - #![allow(clippy::wildcard_imports)] - use arrow::datatypes::*; - DataType::UInt8 - } - - 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::{Loggable as _, ResultExt as _}; - use arrow::{array::*, buffer::*, datatypes::*}; - - #[allow(unused)] - fn as_array_ref(t: T) -> ArrayRef { - std::sync::Arc::new(t) as ArrayRef - } - 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| *datum as u8); - (datum.is_some(), datum) - }) - .unzip(); - let data0_validity: Option = { - let any_nones = somes.iter().any(|some| !*some); - any_nones.then(|| somes.into()) - }; - as_array_ref(PrimitiveArray::::new( - ScalarBuffer::from( - data0 - .into_iter() - .map(|v| v.unwrap_or_default()) - .collect::>(), - ), - data0_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(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.PlaneOrientation#enum")? - .into_iter() - .map(|opt| opt.copied()) - .map(|typ| match typ { - Some(1) => Ok(Some(Self::Xz)), - Some(2) => Ok(Some(Self::Yz)), - Some(3) => Ok(Some(Self::Xy)), - None => Ok(None), - Some(invalid) => Err(DeserializationError::missing_union_arm( - Self::arrow_datatype(), - "", - invalid as _, - )), - }) - .collect::>>>() - .with_context("rerun.blueprint.components.PlaneOrientation")?) - } -} - -impl ::re_types_core::Component for PlaneOrientation { - #[inline] - fn name() -> ComponentName { - "rerun.blueprint.components.PlaneOrientation".into() - } -} diff --git a/crates/store/re_types/src/components/mod.rs b/crates/store/re_types/src/components/mod.rs index 9208eeb9f0e4..c085b8954e44 100644 --- a/crates/store/re_types/src/components/mod.rs +++ b/crates/store/re_types/src/components/mod.rs @@ -63,6 +63,7 @@ mod opacity_ext; mod pinhole_projection; mod pinhole_projection_ext; mod plane3d; +mod plane3d_ext; mod pose_rotation_axis_angle; mod pose_rotation_axis_angle_ext; mod pose_rotation_quat; diff --git a/crates/store/re_types/src/components/plane3d.rs b/crates/store/re_types/src/components/plane3d.rs index fa9ae2ccec49..6a66c38afa7f 100644 --- a/crates/store/re_types/src/components/plane3d.rs +++ b/crates/store/re_types/src/components/plane3d.rs @@ -26,7 +26,7 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; /// Note: although the normal will be passed through to the /// 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 -#[derive(Clone, Debug, Default, Copy, PartialEq, bytemuck::Pod, bytemuck::Zeroable)] +#[derive(Clone, Debug, Copy, PartialEq, bytemuck::Pod, bytemuck::Zeroable)] #[repr(transparent)] pub struct Plane3D(pub crate::datatypes::Plane3D); diff --git a/crates/store/re_types/src/components/plane3d_ext.rs b/crates/store/re_types/src/components/plane3d_ext.rs new file mode 100644 index 000000000000..e51f097de085 --- /dev/null +++ b/crates/store/re_types/src/components/plane3d_ext.rs @@ -0,0 +1,31 @@ +use super::Plane3D; + +impl Plane3D { + /// The Y^Z plane with normal = +X. + pub const YZ: Self = Self(crate::datatypes::Plane3D([1.0, 0.0, 0.0, 0.0])); + + /// The Z^X plane with normal = +Y. + pub const ZX: Self = Self(crate::datatypes::Plane3D([0.0, 1.0, 0.0, 0.0])); + + /// The X^Y plane with normal = +Z. + pub const XY: Self = Self(crate::datatypes::Plane3D([0.0, 0.0, 1.0, 0.0])); + + /// Create a new plane from a normal and distance. + /// + /// The plane will not be normalized upon creation. + pub fn new(normal: impl Into, d: f32) -> Self { + Self(crate::datatypes::Plane3D::new(normal, d)) + } +} + +#[cfg(feature = "glam")] +impl From for re_math::Plane3 { + #[inline] + fn from(plane: Plane3D) -> Self { + Self { + normal: glam::vec3(plane.0 .0[0], plane.0 .0[1], plane.0 .0[2]), + d: plane.0 .0[3], + } + .normalized() + } +} diff --git a/crates/store/re_types/src/datatypes/mod.rs b/crates/store/re_types/src/datatypes/mod.rs index 900981b55636..d1edf377eb08 100644 --- a/crates/store/re_types/src/datatypes/mod.rs +++ b/crates/store/re_types/src/datatypes/mod.rs @@ -31,6 +31,7 @@ mod mat4x4_ext; mod pixel_format; mod pixel_format_ext; mod plane3d; +mod plane3d_ext; mod quaternion; mod quaternion_ext; mod range1d; diff --git a/crates/store/re_types/src/datatypes/plane3d_ext.rs b/crates/store/re_types/src/datatypes/plane3d_ext.rs new file mode 100644 index 000000000000..fea40d230eff --- /dev/null +++ b/crates/store/re_types/src/datatypes/plane3d_ext.rs @@ -0,0 +1,50 @@ +use super::Plane3D; + +impl Plane3D { + /// The Y^Z plane with normal = +X. + pub const YZ: Self = Self([1.0, 0.0, 0.0, 0.0]); + + /// The Z^X plane with normal = +Y. + pub const ZX: Self = Self([0.0, 1.0, 0.0, 0.0]); + + /// The X^Y plane with normal = +Z. + pub const XY: Self = Self([0.0, 0.0, 1.0, 0.0]); + + /// The normal of the plane (unnormalized if the plane is unnormalized). + pub const fn normal(&self) -> super::Vec3D { + super::Vec3D([self.0[0], self.0[1], self.0[2]]) + } + + /// The distance of the plane from the origin (in multiples of the normal if the normal is unnormalized). + pub const fn distance(&self) -> f32 { + self.0[3] + } + + /// Create a new plane from a normal and distance. + /// + /// The plane will not be normalized upon creation. + pub fn new(normal: impl Into, d: f32) -> Self { + let normal = normal.into(); + Self([normal.0[0], normal.0[1], normal.0[2], d]) + } +} + +#[cfg(feature = "glam")] +impl From for Plane3D { + #[inline] + fn from(plane: re_math::Plane3) -> Self { + Self([plane.normal.x, plane.normal.y, plane.normal.z, plane.d]) + } +} + +#[cfg(feature = "glam")] +impl From for re_math::Plane3 { + #[inline] + fn from(plane: Plane3D) -> Self { + Self { + normal: glam::vec3(plane.0[0], plane.0[1], plane.0[2]), + d: plane.0[3], + } + .normalized() + } +} diff --git a/crates/viewer/re_component_ui/src/lib.rs b/crates/viewer/re_component_ui/src/lib.rs index 6ea5900092ef..bdb8339a7102 100644 --- a/crates/viewer/re_component_ui/src/lib.rs +++ b/crates/viewer/re_component_ui/src/lib.rs @@ -34,8 +34,8 @@ use datatype_uis::{ use re_types::{ blueprint::components::{ - BackgroundKind, Corner2D, GridSpacing, LockRangeDuringZoom, MapProvider, PlaneOffset, - PlaneOrientation, UiRadius, ViewFit, Visible, + BackgroundKind, Corner2D, GridSpacing, LockRangeDuringZoom, MapProvider, UiRadius, ViewFit, + Visible, }, components::{ AggregationPolicy, AlbedoFactor, AxisLength, Color, DepthMeter, DrawOrder, FillMode, @@ -80,7 +80,6 @@ pub fn create_component_ui_registry() -> re_viewer_context::ComponentUiRegistry // float min-max components: registry.add_singleline_edit_or_view::(edit_f32_min_to_max_float); - registry.add_singleline_edit_or_view::(edit_f32_min_to_max_float); // float 0-1 components: registry.add_singleline_edit_or_view::(edit_f32_zero_to_one); @@ -106,7 +105,6 @@ pub fn create_component_ui_registry() -> re_viewer_context::ComponentUiRegistry registry.add_singleline_edit_or_view::(edit_view_enum); registry.add_singleline_edit_or_view::(edit_view_enum); registry.add_singleline_edit_or_view::(edit_view_enum); - registry.add_singleline_edit_or_view::(edit_view_enum); registry.add_singleline_edit_or_view::( edit_view_enum_with_variant_available::< MapProvider, @@ -173,5 +171,7 @@ pub fn create_component_ui_registry() -> re_viewer_context::ComponentUiRegistry registry.add_singleline_edit_or_view(zoom_level::edit_zoom_level); + // TODO: add ui for plane + registry } diff --git a/crates/viewer/re_space_view_spatial/src/ui_3d.rs b/crates/viewer/re_space_view_spatial/src/ui_3d.rs index d3624ee390c0..294912118ed0 100644 --- a/crates/viewer/re_space_view_spatial/src/ui_3d.rs +++ b/crates/viewer/re_space_view_spatial/src/ui_3d.rs @@ -15,7 +15,7 @@ use re_space_view::controls::{ use re_types::{ blueprint::{ archetypes::{Background, LineGrid3D}, - components::{GridSpacing, PlaneOffset, PlaneOrientation, UiRadius, Visible}, + components::{GridSpacing, UiRadius, Visible}, }, components::ViewCoordinates, view_coordinates::SignedAxis3, @@ -726,14 +726,8 @@ impl SpatialSpaceView3D { (**grid_config.component_or_fallback::(ctx, self, state)?) * 2.0; let color = grid_config.component_or_fallback::(ctx, self, state)?; - let orientation = - grid_config.component_or_fallback::(ctx, self, state)?; - let normal_offset = **grid_config.component_or_fallback::(ctx, self, state)?; - let plane = match orientation { - PlaneOrientation::Xy => re_math::Plane3::from_normal_dist(glam::Vec3::Z, normal_offset), - PlaneOrientation::Yz => re_math::Plane3::from_normal_dist(glam::Vec3::X, normal_offset), - PlaneOrientation::Xz => re_math::Plane3::from_normal_dist(glam::Vec3::Y, normal_offset), - }; + let plane = + grid_config.component_or_fallback::(ctx, self, state)?; let Some(render_ctx) = ctx.render_ctx else { return Ok(None); @@ -743,7 +737,7 @@ impl SpatialSpaceView3D { render_ctx, &re_renderer::renderer::WorldGridConfiguration { color: color.into(), - plane, + plane: plane.into(), spacing, thickness_ui, }, diff --git a/crates/viewer/re_space_view_spatial/src/view_3d_properties.rs b/crates/viewer/re_space_view_spatial/src/view_3d_properties.rs index 5c37d70c1a72..bae1c97c94a3 100644 --- a/crates/viewer/re_space_view_spatial/src/view_3d_properties.rs +++ b/crates/viewer/re_space_view_spatial/src/view_3d_properties.rs @@ -1,9 +1,9 @@ use re_types::{ blueprint::{ archetypes::{Background, LineGrid3D}, - components::{BackgroundKind, PlaneOrientation, UiRadius}, + components::{BackgroundKind, UiRadius}, }, - components::Color, + components::{Color, Plane3D}, Archetype, }; use re_viewer_context::{SpaceViewStateExt as _, TypedComponentFallbackProvider}; @@ -40,22 +40,24 @@ impl TypedComponentFallbackProvider for SpatialSpaceView3D { } } -impl TypedComponentFallbackProvider for SpatialSpaceView3D { - fn fallback_for(&self, ctx: &re_viewer_context::QueryContext<'_>) -> PlaneOrientation { +impl TypedComponentFallbackProvider for SpatialSpaceView3D { + fn fallback_for(&self, ctx: &re_viewer_context::QueryContext<'_>) -> Plane3D { + const DEFAULT_PLANE: Plane3D = Plane3D::XY; + let Ok(view_state) = ctx.view_state.downcast_ref::() else { - return PlaneOrientation::default(); + return DEFAULT_PLANE; }; view_state .state_3d .scene_view_coordinates .and_then(|view_coordinates| view_coordinates.up()) - .map_or(PlaneOrientation::default(), |up| match up.axis { - re_types::view_coordinates::Axis3::X => PlaneOrientation::Yz, - re_types::view_coordinates::Axis3::Y => PlaneOrientation::Xz, - re_types::view_coordinates::Axis3::Z => PlaneOrientation::Xy, + .map_or(DEFAULT_PLANE, |up| match up.axis { + re_types::view_coordinates::Axis3::X => Plane3D::YZ, + re_types::view_coordinates::Axis3::Y => Plane3D::ZX, + re_types::view_coordinates::Axis3::Z => Plane3D::XY, }) } } -re_viewer_context::impl_component_fallback_provider!(SpatialSpaceView3D => [BackgroundKind, Color, UiRadius, PlaneOrientation]); +re_viewer_context::impl_component_fallback_provider!(SpatialSpaceView3D => [BackgroundKind, Color, UiRadius, Plane3D]); diff --git a/crates/viewer/re_viewer/src/blueprint/validation_gen/mod.rs b/crates/viewer/re_viewer/src/blueprint/validation_gen/mod.rs index 3c42dcb8b65e..7d045fbfe00d 100644 --- a/crates/viewer/re_viewer/src/blueprint/validation_gen/mod.rs +++ b/crates/viewer/re_viewer/src/blueprint/validation_gen/mod.rs @@ -15,8 +15,6 @@ pub use re_types::blueprint::components::Interactive; pub use re_types::blueprint::components::LockRangeDuringZoom; pub use re_types::blueprint::components::MapProvider; pub use re_types::blueprint::components::PanelState; -pub use re_types::blueprint::components::PlaneOffset; -pub use re_types::blueprint::components::PlaneOrientation; pub use re_types::blueprint::components::QueryExpression; pub use re_types::blueprint::components::RowShare; pub use re_types::blueprint::components::SelectedColumns; @@ -61,8 +59,6 @@ pub fn is_valid_blueprint(blueprint: &EntityDb) -> bool { && validate_component::(blueprint) && validate_component::(blueprint) && validate_component::(blueprint) - && validate_component::(blueprint) - && validate_component::(blueprint) && validate_component::(blueprint) && validate_component::(blueprint) && validate_component::(blueprint) diff --git a/crates/viewer/re_viewer/src/reflection/mod.rs b/crates/viewer/re_viewer/src/reflection/mod.rs index bb9b81daea31..6a6ce1a73c7c 100644 --- a/crates/viewer/re_viewer/src/reflection/mod.rs +++ b/crates/viewer/re_viewer/src/reflection/mod.rs @@ -180,22 +180,6 @@ fn generate_component_reflection() -> Result::name(), - ComponentReflection { - docstring_md: "Offset of a plane along its normal in scene units.", - custom_placeholder: Some(PlaneOffset::default().to_arrow2()?), - datatype: PlaneOffset::arrow2_datatype(), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "Orientation of a 3D axis aligned plane.", - custom_placeholder: Some(PlaneOrientation::default().to_arrow2()?), - datatype: PlaneOrientation::arrow2_datatype(), - }, - ), ( ::name(), ComponentReflection { @@ -636,7 +620,7 @@ fn generate_component_reflection() -> Result::name(), ComponentReflection { docstring_md: "An infinite 3D plane represented by a unit normal vector and a distance.\n\nAny point P on the plane fulfills the equation `dot(xyz, P) - d = 0`, where `xyz` is the plane's normal and `d` the distance.\nThis representation is also known as the Hesse normal form, see https://en.wikipedia.org/wiki/Hesse_normal_form\n\nNote: although the normal will be passed through to the\ndatastore as provided, when used in the Viewer, planes will always be normalized.\nI.e. the plane with xyz = (2, 0, 0), d = 1 is equivalent to xyz = (1, 0, 0), d = 0.5", - custom_placeholder: Some(Plane3D::default().to_arrow2()?), + custom_placeholder: None, datatype: Plane3D::arrow2_datatype(), }, ), @@ -1985,12 +1969,9 @@ fn generate_archetype_reflection() -> ArchetypeReflectionMap { "Spacing", docstring_md : "Space between grid lines spacing of one line to the next in scene units.", is_required : false, }, ArchetypeFieldReflection { component_name : - "rerun.blueprint.components.PlaneOrientation".into(), display_name : - "Orientation", docstring_md : - "How the grid is oriented.\n\nDefaults to whatever plane is determined as the down plane by view coordinates if present.", - is_required : false, }, ArchetypeFieldReflection { component_name : - "rerun.blueprint.components.PlaneOffset".into(), display_name : - "Offset", docstring_md : "Offset of the grid along its normal.", + "rerun.components.Plane3D".into(), display_name : "Plane", + docstring_md : + "In what plane the grid is drawn.\n\nDefaults to whatever plane is determined as the plane at zero units up/down as defined by [`archetype.ViewCoordinates`] if present.", is_required : false, }, ArchetypeFieldReflection { component_name : "rerun.blueprint.components.UiRadius".into(), display_name : "Line radius", docstring_md : diff --git a/docs/content/reference/types/views/spatial3d_view.md b/docs/content/reference/types/views/spatial3d_view.md index 546e8dc017a6..d375741e0644 100644 --- a/docs/content/reference/types/views/spatial3d_view.md +++ b/docs/content/reference/types/views/spatial3d_view.md @@ -17,8 +17,7 @@ Configuration for the 3D line grid. * `visible`: Whether the grid is visible. * `spacing`: Space between grid lines spacing of one line to the next in scene units. -* `orientation`: How the grid is oriented. -* `offset`: Offset of the grid along its normal. +* `plane`: In what plane the grid is drawn. * `line_radius`: How thick the lines should be in ui units. * `color`: Color used for the grid. ### `time_ranges` diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.cpp b/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.cpp index 3a7f27a71485..7d88029b2092 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.cpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.cpp @@ -14,7 +14,7 @@ namespace rerun { ) { using namespace blueprint::archetypes; std::vector cells; - cells.reserve(7); + cells.reserve(6); if (archetype.visible.has_value()) { auto result = ComponentBatch::from_loggable(archetype.visible.value()); @@ -26,13 +26,8 @@ namespace rerun { RR_RETURN_NOT_OK(result.error); cells.push_back(std::move(result.value)); } - if (archetype.orientation.has_value()) { - auto result = ComponentBatch::from_loggable(archetype.orientation.value()); - RR_RETURN_NOT_OK(result.error); - cells.push_back(std::move(result.value)); - } - if (archetype.offset.has_value()) { - auto result = ComponentBatch::from_loggable(archetype.offset.value()); + if (archetype.plane.has_value()) { + auto result = ComponentBatch::from_loggable(archetype.plane.value()); RR_RETURN_NOT_OK(result.error); cells.push_back(std::move(result.value)); } diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.hpp b/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.hpp index b66da9203486..89bb801d47ac 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.hpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.hpp @@ -4,14 +4,13 @@ #pragma once #include "../../blueprint/components/grid_spacing.hpp" -#include "../../blueprint/components/plane_offset.hpp" -#include "../../blueprint/components/plane_orientation.hpp" #include "../../blueprint/components/ui_radius.hpp" #include "../../blueprint/components/visible.hpp" #include "../../collection.hpp" #include "../../compiler_utils.hpp" #include "../../component_batch.hpp" #include "../../components/color.hpp" +#include "../../components/plane3d.hpp" #include "../../indicator_component.hpp" #include "../../result.hpp" @@ -31,13 +30,10 @@ namespace rerun::blueprint::archetypes { /// Space between grid lines spacing of one line to the next in scene units. std::optional spacing; - /// How the grid is oriented. + /// In what plane the grid is drawn. /// - /// Defaults to whatever plane is determined as the down plane by view coordinates if present. - std::optional orientation; - - /// Offset of the grid along its normal. - std::optional offset; + /// Defaults to whatever plane is determined as the plane at zero units up/down as defined by [`archetype.ViewCoordinates`] if present. + std::optional plane; /// How thick the lines should be in ui units. /// @@ -77,19 +73,11 @@ namespace rerun::blueprint::archetypes { RR_WITH_MAYBE_UNINITIALIZED_DISABLED(return std::move(*this);) } - /// How the grid is oriented. + /// In what plane the grid is drawn. /// - /// Defaults to whatever plane is determined as the down plane by view coordinates if present. - LineGrid3D with_orientation(rerun::blueprint::components::PlaneOrientation _orientation - ) && { - orientation = std::move(_orientation); - // See: https://github.com/rerun-io/rerun/issues/4027 - RR_WITH_MAYBE_UNINITIALIZED_DISABLED(return std::move(*this);) - } - - /// Offset of the grid along its normal. - LineGrid3D with_offset(rerun::blueprint::components::PlaneOffset _offset) && { - offset = std::move(_offset); + /// Defaults to whatever plane is determined as the plane at zero units up/down as defined by [`archetype.ViewCoordinates`] if present. + LineGrid3D with_plane(rerun::components::Plane3D _plane) && { + plane = std::move(_plane); // See: https://github.com/rerun-io/rerun/issues/4027 RR_WITH_MAYBE_UNINITIALIZED_DISABLED(return std::move(*this);) } diff --git a/rerun_cpp/src/rerun/blueprint/components.hpp b/rerun_cpp/src/rerun/blueprint/components.hpp index 9db96efea076..3cbea75f71f0 100644 --- a/rerun_cpp/src/rerun/blueprint/components.hpp +++ b/rerun_cpp/src/rerun/blueprint/components.hpp @@ -20,8 +20,6 @@ #include "blueprint/components/lock_range_during_zoom.hpp" #include "blueprint/components/map_provider.hpp" #include "blueprint/components/panel_state.hpp" -#include "blueprint/components/plane_offset.hpp" -#include "blueprint/components/plane_orientation.hpp" #include "blueprint/components/query_expression.hpp" #include "blueprint/components/root_container.hpp" #include "blueprint/components/row_share.hpp" diff --git a/rerun_cpp/src/rerun/blueprint/components/.gitattributes b/rerun_cpp/src/rerun/blueprint/components/.gitattributes index ba91739ef669..f1f37065f76c 100644 --- a/rerun_cpp/src/rerun/blueprint/components/.gitattributes +++ b/rerun_cpp/src/rerun/blueprint/components/.gitattributes @@ -24,9 +24,6 @@ map_provider.cpp linguist-generated=true map_provider.hpp linguist-generated=true panel_state.cpp linguist-generated=true panel_state.hpp linguist-generated=true -plane_offset.hpp linguist-generated=true -plane_orientation.cpp linguist-generated=true -plane_orientation.hpp linguist-generated=true query_expression.hpp linguist-generated=true root_container.hpp linguist-generated=true row_share.hpp linguist-generated=true diff --git a/rerun_cpp/src/rerun/blueprint/components/plane_offset.hpp b/rerun_cpp/src/rerun/blueprint/components/plane_offset.hpp deleted file mode 100644 index e30aa1715701..000000000000 --- a/rerun_cpp/src/rerun/blueprint/components/plane_offset.hpp +++ /dev/null @@ -1,74 +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/blueprint/components/plane_offset.fbs". - -#pragma once - -#include "../../datatypes/float32.hpp" -#include "../../result.hpp" - -#include -#include - -namespace rerun::blueprint::components { - /// **Component**: Offset of a plane along its normal in scene units. - struct PlaneOffset { - /// Offset of a plane along its normal in scene units. - rerun::datatypes::Float32 distance; - - public: - PlaneOffset() = default; - - PlaneOffset(rerun::datatypes::Float32 distance_) : distance(distance_) {} - - PlaneOffset& operator=(rerun::datatypes::Float32 distance_) { - distance = distance_; - return *this; - } - - PlaneOffset(float value_) : distance(value_) {} - - PlaneOffset& operator=(float value_) { - distance = value_; - return *this; - } - - /// Cast to the underlying Float32 datatype - operator rerun::datatypes::Float32() const { - return distance; - } - }; -} // namespace rerun::blueprint::components - -namespace rerun { - static_assert(sizeof(rerun::datatypes::Float32) == sizeof(blueprint::components::PlaneOffset)); - - /// \private - template <> - struct Loggable { - static constexpr const char Name[] = "rerun.blueprint.components.PlaneOffset"; - - /// Returns the arrow data type this type corresponds to. - static const std::shared_ptr& arrow_datatype() { - return Loggable::arrow_datatype(); - } - - /// Serializes an array of `rerun::blueprint:: components::PlaneOffset` into an arrow array. - static Result> to_arrow( - const blueprint::components::PlaneOffset* instances, size_t num_instances - ) { - if (num_instances == 0) { - return Loggable::to_arrow(nullptr, 0); - } else if (instances == nullptr) { - return rerun::Error( - ErrorCode::UnexpectedNullArgument, - "Passed array instances is null when num_elements> 0." - ); - } else { - return Loggable::to_arrow( - &instances->distance, - num_instances - ); - } - } - }; -} // namespace rerun diff --git a/rerun_cpp/src/rerun/blueprint/components/plane_orientation.cpp b/rerun_cpp/src/rerun/blueprint/components/plane_orientation.cpp deleted file mode 100644 index 5fce189de63c..000000000000 --- a/rerun_cpp/src/rerun/blueprint/components/plane_orientation.cpp +++ /dev/null @@ -1,61 +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/blueprint/components/plane_orientation.fbs". - -#include "plane_orientation.hpp" - -#include -#include - -namespace rerun { - const std::shared_ptr& - Loggable::arrow_datatype() { - static const auto datatype = arrow::uint8(); - return datatype; - } - - Result> - Loggable::to_arrow( - const blueprint::components::PlaneOrientation* 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::UInt8Builder* builder, const blueprint::components::PlaneOrientation* 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." - ); - } - - ARROW_RETURN_NOT_OK(builder->Reserve(static_cast(num_elements))); - for (size_t elem_idx = 0; elem_idx < num_elements; elem_idx += 1) { - const auto variant = elements[elem_idx]; - ARROW_RETURN_NOT_OK(builder->Append(static_cast(variant))); - } - - return Error::ok(); - } -} // namespace rerun diff --git a/rerun_cpp/src/rerun/blueprint/components/plane_orientation.hpp b/rerun_cpp/src/rerun/blueprint/components/plane_orientation.hpp deleted file mode 100644 index 3ee04df0bfea..000000000000 --- a/rerun_cpp/src/rerun/blueprint/components/plane_orientation.hpp +++ /dev/null @@ -1,60 +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/blueprint/components/plane_orientation.fbs". - -#pragma once - -#include "../../result.hpp" - -#include -#include - -namespace arrow { - /// \private - template - class NumericBuilder; - - class Array; - class DataType; - class UInt8Type; - using UInt8Builder = NumericBuilder; -} // namespace arrow - -namespace rerun::blueprint::components { - /// **Component**: Orientation of a 3D axis aligned plane. - enum class PlaneOrientation : uint8_t { - - /// Plane spanned by X and Z axis. - Xz = 1, - - /// Plane spanned by Y and Z axis. - Yz = 2, - - /// Plane spanned by X and Y axis. - Xy = 3, - }; -} // namespace rerun::blueprint::components - -namespace rerun { - template - struct Loggable; - - /// \private - template <> - struct Loggable { - static constexpr const char Name[] = "rerun.blueprint.components.PlaneOrientation"; - - /// Returns the arrow data type this type corresponds to. - static const std::shared_ptr& arrow_datatype(); - - /// Serializes an array of `rerun::blueprint:: components::PlaneOrientation` into an arrow array. - static Result> to_arrow( - const blueprint::components::PlaneOrientation* instances, size_t num_instances - ); - - /// Fills an arrow array builder with an array of this type. - static rerun::Error fill_arrow_array_builder( - arrow::UInt8Builder* builder, const blueprint::components::PlaneOrientation* elements, - size_t num_elements - ); - }; -} // namespace rerun diff --git a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/line_grid3d.py b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/line_grid3d.py index e3f003243445..bec846001ae5 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/line_grid3d.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/line_grid3d.py @@ -28,8 +28,7 @@ def __init__( *, visible: datatypes.BoolLike | None = None, spacing: datatypes.Float32Like | None = None, - orientation: blueprint_components.PlaneOrientationLike | None = None, - offset: datatypes.Float32Like | None = None, + plane: datatypes.Plane3DLike | None = None, line_radius: datatypes.Float32Like | None = None, color: datatypes.Rgba32Like | None = None, ): @@ -44,12 +43,10 @@ def __init__( Defaults to true. spacing: Space between grid lines spacing of one line to the next in scene units. - orientation: - How the grid is oriented. + plane: + In what plane the grid is drawn. - Defaults to whatever plane is determined as the down plane by view coordinates if present. - offset: - Offset of the grid along its normal. + Defaults to whatever plane is determined as the plane at zero units up/down as defined by [`archetype.ViewCoordinates`] if present. line_radius: How thick the lines should be in ui units. @@ -64,14 +61,7 @@ def __init__( # You can define your own __init__ function as a member of LineGrid3DExt in line_grid3d_ext.py with catch_and_log_exceptions(context=self.__class__.__name__): - self.__attrs_init__( - visible=visible, - spacing=spacing, - orientation=orientation, - offset=offset, - line_radius=line_radius, - color=color, - ) + self.__attrs_init__(visible=visible, spacing=spacing, plane=plane, line_radius=line_radius, color=color) return self.__attrs_clear__() @@ -80,8 +70,7 @@ def __attrs_clear__(self) -> None: self.__attrs_init__( visible=None, # type: ignore[arg-type] spacing=None, # type: ignore[arg-type] - orientation=None, # type: ignore[arg-type] - offset=None, # type: ignore[arg-type] + plane=None, # type: ignore[arg-type] line_radius=None, # type: ignore[arg-type] color=None, # type: ignore[arg-type] ) @@ -113,23 +102,14 @@ def _clear(cls) -> LineGrid3D: # # (Docstring intentionally commented out to hide this field from the docs) - orientation: blueprint_components.PlaneOrientationBatch | None = field( + plane: components.Plane3DBatch | None = field( metadata={"component": "optional"}, default=None, - converter=blueprint_components.PlaneOrientationBatch._optional, # type: ignore[misc] + converter=components.Plane3DBatch._optional, # type: ignore[misc] ) - # How the grid is oriented. + # In what plane the grid is drawn. # - # Defaults to whatever plane is determined as the down plane by view coordinates if present. - # - # (Docstring intentionally commented out to hide this field from the docs) - - offset: blueprint_components.PlaneOffsetBatch | None = field( - metadata={"component": "optional"}, - default=None, - converter=blueprint_components.PlaneOffsetBatch._optional, # type: ignore[misc] - ) - # Offset of the grid along its normal. + # Defaults to whatever plane is determined as the plane at zero units up/down as defined by [`archetype.ViewCoordinates`] if present. # # (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 9668112db835..d613772faf83 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/components/.gitattributes +++ b/rerun_py/rerun_sdk/rerun/blueprint/components/.gitattributes @@ -20,8 +20,6 @@ interactive.py linguist-generated=true lock_range_during_zoom.py linguist-generated=true map_provider.py linguist-generated=true panel_state.py linguist-generated=true -plane_offset.py linguist-generated=true -plane_orientation.py linguist-generated=true query_expression.py linguist-generated=true root_container.py linguist-generated=true row_share.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 267a38176fd9..ef4d270cad7a 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/components/__init__.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/components/__init__.py @@ -20,8 +20,6 @@ from .lock_range_during_zoom import LockRangeDuringZoom, LockRangeDuringZoomBatch from .map_provider import MapProvider, MapProviderArrayLike, MapProviderBatch, MapProviderLike from .panel_state import PanelState, PanelStateArrayLike, PanelStateBatch, PanelStateLike -from .plane_offset import PlaneOffset, PlaneOffsetBatch -from .plane_orientation import PlaneOrientation, PlaneOrientationArrayLike, PlaneOrientationBatch, PlaneOrientationLike from .query_expression import QueryExpression, QueryExpressionBatch from .root_container import RootContainer, RootContainerBatch from .row_share import RowShare, RowShareBatch @@ -87,12 +85,6 @@ "PanelStateArrayLike", "PanelStateBatch", "PanelStateLike", - "PlaneOffset", - "PlaneOffsetBatch", - "PlaneOrientation", - "PlaneOrientationArrayLike", - "PlaneOrientationBatch", - "PlaneOrientationLike", "QueryExpression", "QueryExpressionBatch", "RootContainer", diff --git a/rerun_py/rerun_sdk/rerun/blueprint/components/plane_offset.py b/rerun_py/rerun_sdk/rerun/blueprint/components/plane_offset.py deleted file mode 100644 index 1b89b6a00c2d..000000000000 --- a/rerun_py/rerun_sdk/rerun/blueprint/components/plane_offset.py +++ /dev/null @@ -1,32 +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/blueprint/components/plane_offset.fbs". - -# You can extend this class by creating a "PlaneOffsetExt" class in "plane_offset_ext.py". - -from __future__ import annotations - -from ... import datatypes -from ..._baseclasses import ( - ComponentBatchMixin, - ComponentMixin, -) - -__all__ = ["PlaneOffset", "PlaneOffsetBatch"] - - -class PlaneOffset(datatypes.Float32, ComponentMixin): - """**Component**: Offset of a plane along its normal in scene units.""" - - _BATCH_TYPE = None - # You can define your own __init__ function as a member of PlaneOffsetExt in plane_offset_ext.py - - # Note: there are no fields here because PlaneOffset delegates to datatypes.Float32 - pass - - -class PlaneOffsetBatch(datatypes.Float32Batch, ComponentBatchMixin): - _COMPONENT_NAME: str = "rerun.blueprint.components.PlaneOffset" - - -# This is patched in late to avoid circular dependencies. -PlaneOffset._BATCH_TYPE = PlaneOffsetBatch # type: ignore[assignment] diff --git a/rerun_py/rerun_sdk/rerun/blueprint/components/plane_orientation.py b/rerun_py/rerun_sdk/rerun/blueprint/components/plane_orientation.py deleted file mode 100644 index 07ed958eaf2e..000000000000 --- a/rerun_py/rerun_sdk/rerun/blueprint/components/plane_orientation.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/blueprint/components/plane_orientation.fbs". - -# You can extend this class by creating a "PlaneOrientationExt" class in "plane_orientation_ext.py". - -from __future__ import annotations - -from typing import Literal, Sequence, Union - -import pyarrow as pa - -from ..._baseclasses import ( - BaseBatch, - ComponentBatchMixin, -) - -__all__ = ["PlaneOrientation", "PlaneOrientationArrayLike", "PlaneOrientationBatch", "PlaneOrientationLike"] - - -from enum import Enum - - -class PlaneOrientation(Enum): - """**Component**: Orientation of a 3D axis aligned plane.""" - - Xz = 1 - """Plane spanned by X and Z axis.""" - - Yz = 2 - """Plane spanned by Y and Z axis.""" - - Xy = 3 - """Plane spanned by X and Y axis.""" - - @classmethod - def auto(cls, val: str | int | PlaneOrientation) -> PlaneOrientation: - """Best-effort converter, including a case-insensitive string matcher.""" - if isinstance(val, PlaneOrientation): - return val - if isinstance(val, int): - return cls(val) - try: - return cls[val] - except KeyError: - val_lower = val.lower() - for variant in cls: - if variant.name.lower() == val_lower: - return variant - raise ValueError(f"Cannot convert {val} to {cls.__name__}") - - def __str__(self) -> str: - """Returns the variant name.""" - return self.name - - -PlaneOrientationLike = Union[PlaneOrientation, Literal["Xy", "Xz", "Yz", "xy", "xz", "yz"], int] -PlaneOrientationArrayLike = Union[PlaneOrientationLike, Sequence[PlaneOrientationLike]] - - -class PlaneOrientationBatch(BaseBatch[PlaneOrientationArrayLike], ComponentBatchMixin): - _ARROW_DATATYPE = pa.uint8() - _COMPONENT_NAME: str = "rerun.blueprint.components.PlaneOrientation" - - @staticmethod - def _native_to_pa_array(data: PlaneOrientationArrayLike, data_type: pa.DataType) -> pa.Array: - if isinstance(data, (PlaneOrientation, int, str)): - data = [data] - - pa_data = [PlaneOrientation.auto(v).value if v is not None else None for v in data] # type: ignore[redundant-expr] - - return pa.array(pa_data, type=data_type) From 8c890e4f28cfd95e313e03a711e0dc032217de02 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Tue, 3 Dec 2024 12:10:53 +0100 Subject: [PATCH 12/29] wip ui for plane 3d --- .../src/datatype_uis/float_drag.rs | 6 +-- .../re_component_ui/src/datatype_uis/mod.rs | 4 +- .../re_component_ui/src/datatype_uis/vec.rs | 8 ++-- crates/viewer/re_component_ui/src/lib.rs | 1 + crates/viewer/re_component_ui/src/plane3d.rs | 42 +++++++++++++++++++ 5 files changed, 52 insertions(+), 9 deletions(-) create mode 100644 crates/viewer/re_component_ui/src/plane3d.rs diff --git a/crates/viewer/re_component_ui/src/datatype_uis/float_drag.rs b/crates/viewer/re_component_ui/src/datatype_uis/float_drag.rs index 4ab88fe24ce8..7b3b2f970e3a 100644 --- a/crates/viewer/re_component_ui/src/datatype_uis/float_drag.rs +++ b/crates/viewer/re_component_ui/src/datatype_uis/float_drag.rs @@ -14,7 +14,7 @@ pub fn edit_f32_zero_to_max( MaybeMutRef::Ref(value) => MaybeMutRef::Ref(value), MaybeMutRef::MutRef(value) => MaybeMutRef::MutRef(&mut value.deref_mut().0), }; - edit_f32_float_raw_impl(ui, &mut value, 0.0..=f32::MAX) + edit_f32_float_raw(ui, &mut value, 0.0..=f32::MAX) } /// Generic editor for a [`re_types::datatypes::Float32`] value from min to max float. @@ -27,11 +27,11 @@ pub fn edit_f32_min_to_max_float( MaybeMutRef::Ref(value) => MaybeMutRef::Ref(value), MaybeMutRef::MutRef(value) => MaybeMutRef::MutRef(&mut value.deref_mut().0), }; - edit_f32_float_raw_impl(ui, &mut value, f32::MIN..=f32::MAX) + edit_f32_float_raw(ui, &mut value, f32::MIN..=f32::MAX) } /// Non monomorphized implementation for f32 float editing. -pub fn edit_f32_float_raw_impl( +pub fn edit_f32_float_raw( ui: &mut egui::Ui, value: &mut MaybeMutRef<'_, f32>, range: RangeInclusive, diff --git a/crates/viewer/re_component_ui/src/datatype_uis/mod.rs b/crates/viewer/re_component_ui/src/datatype_uis/mod.rs index 54d66fbacfd3..33e6997985c8 100644 --- a/crates/viewer/re_component_ui/src/datatype_uis/mod.rs +++ b/crates/viewer/re_component_ui/src/datatype_uis/mod.rs @@ -13,13 +13,13 @@ pub use enum_combobox::{ VariantAvailableProvider, }; pub use float_drag::{ - edit_f32_min_to_max_float, edit_f32_zero_to_max, edit_f32_zero_to_one, + edit_f32_float_raw, edit_f32_min_to_max_float, edit_f32_zero_to_max, edit_f32_zero_to_one, edit_f64_float_raw_with_speed_impl, }; pub use range1d::edit_view_range1d; pub use singleline_string::{ display_name_ui, display_text_ui, edit_multiline_string, edit_singleline_string, }; -pub use vec::edit_or_view_vec3d; +pub use vec::{edit_or_view_vec3d, edit_or_view_vec3d_raw}; pub use view_id::view_view_id; pub use view_uuid::view_uuid; diff --git a/crates/viewer/re_component_ui/src/datatype_uis/vec.rs b/crates/viewer/re_component_ui/src/datatype_uis/vec.rs index ff78227b6ca4..b28bf039d3f6 100644 --- a/crates/viewer/re_component_ui/src/datatype_uis/vec.rs +++ b/crates/viewer/re_component_ui/src/datatype_uis/vec.rs @@ -1,7 +1,7 @@ use re_types::datatypes; use re_viewer_context::MaybeMutRef; -use super::float_drag::edit_f32_float_raw_impl; +use super::float_drag::edit_f32_float_raw; pub fn edit_or_view_vec3d( _ctx: &re_viewer_context::ViewerContext<'_>, @@ -12,10 +12,10 @@ pub fn edit_or_view_vec3d( MaybeMutRef::Ref(value) => MaybeMutRef::Ref(value), MaybeMutRef::MutRef(value) => MaybeMutRef::MutRef(value), }; - edit_or_view_vec3d_impl(ui, &mut value) + edit_or_view_vec3d_raw(ui, &mut value) } -fn edit_or_view_vec3d_impl( +pub fn edit_or_view_vec3d_raw( ui: &mut egui::Ui, value: &mut MaybeMutRef<'_, datatypes::Vec3D>, ) -> egui::Response { @@ -35,5 +35,5 @@ fn edit_or_view_vector_component( //MaybeMutRef::MutRef(value) => MaybeMutRef::MutRef(&mut value[i]), MaybeMutRef::MutRef(value) => MaybeMutRef::Ref(&value[i]), }; - edit_f32_float_raw_impl(ui, &mut value, f32::MIN..=f32::MAX) + edit_f32_float_raw(ui, &mut value, f32::MIN..=f32::MAX) } diff --git a/crates/viewer/re_component_ui/src/lib.rs b/crates/viewer/re_component_ui/src/lib.rs index bdb8339a7102..59d49fcb7cb6 100644 --- a/crates/viewer/re_component_ui/src/lib.rs +++ b/crates/viewer/re_component_ui/src/lib.rs @@ -14,6 +14,7 @@ mod line_strip; mod map_provider; mod marker_shape; mod pinhole; +mod plane3d; mod radius; mod recording_uri; mod resolution; diff --git a/crates/viewer/re_component_ui/src/plane3d.rs b/crates/viewer/re_component_ui/src/plane3d.rs new file mode 100644 index 000000000000..9e0433519c11 --- /dev/null +++ b/crates/viewer/re_component_ui/src/plane3d.rs @@ -0,0 +1,42 @@ +use re_types::datatypes; +use re_viewer_context::MaybeMutRef; + +use crate::datatype_uis::{edit_f32_float_raw, edit_or_view_vec3d_raw}; + +pub fn edit_or_view_plane3d( + _ctx: &re_viewer_context::ViewerContext<'_>, + ui: &mut egui::Ui, + value: &mut MaybeMutRef<'_, impl std::ops::DerefMut>, +) -> egui::Response { + let mut value: MaybeMutRef<'_, datatypes::Plane3D> = match value { + MaybeMutRef::Ref(value) => MaybeMutRef::Ref(value), + MaybeMutRef::MutRef(value) => MaybeMutRef::MutRef(value), + }; + edit_or_view_plane3d_impl(ui, &mut value) +} + +fn edit_or_view_plane3d_impl( + ui: &mut egui::Ui, + value: &mut MaybeMutRef<'_, datatypes::Plane3D>, +) -> egui::Response { + let mut normal = value.normal(); + let mut distance = value.distance(); + let (mut maybe_mut_normal, mut maybe_mutdistance) = match value { + MaybeMutRef::Ref(value) => (MaybeMutRef::Ref(&normal), MaybeMutRef::Ref(&distance)), + MaybeMutRef::MutRef(value) => ( + MaybeMutRef::MutRef(&mut normal), + MaybeMutRef::MutRef(&mut distance), + ), + }; + + ui.label("n"); + let normal_response = edit_or_view_vec3d_raw(ui, &mut maybe_mut_normal); + ui.label("d"); + let distance_response = edit_f32_float_raw(ui, &mut maybe_mutdistance, f32::MIN..=f32::MAX); + + if let MaybeMutRef::MutRef(value) = value { + **value = datatypes::Plane3D::new(normal, distance); + } + + normal_response.union(distance_response) +} From d257fd6372eca019b89fae303fd6853759a662e9 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Tue, 3 Dec 2024 14:39:46 +0100 Subject: [PATCH 13/29] multi line edit for plane --- .../re_types/src/components/plane3d_ext.rs | 1 + .../re_types/src/datatypes/plane3d_ext.rs | 3 + .../re_component_ui/src/datatype_uis/vec.rs | 30 ++- crates/viewer/re_component_ui/src/lib.rs | 3 +- crates/viewer/re_component_ui/src/plane3d.rs | 172 +++++++++++++++--- .../src/view_3d_properties.rs | 6 +- 6 files changed, 179 insertions(+), 36 deletions(-) diff --git a/crates/store/re_types/src/components/plane3d_ext.rs b/crates/store/re_types/src/components/plane3d_ext.rs index e51f097de085..5696bb1cf673 100644 --- a/crates/store/re_types/src/components/plane3d_ext.rs +++ b/crates/store/re_types/src/components/plane3d_ext.rs @@ -13,6 +13,7 @@ impl Plane3D { /// Create a new plane from a normal and distance. /// /// The plane will not be normalized upon creation. + #[inline] pub fn new(normal: impl Into, d: f32) -> Self { Self(crate::datatypes::Plane3D::new(normal, d)) } diff --git a/crates/store/re_types/src/datatypes/plane3d_ext.rs b/crates/store/re_types/src/datatypes/plane3d_ext.rs index fea40d230eff..b71e5b3d4b5b 100644 --- a/crates/store/re_types/src/datatypes/plane3d_ext.rs +++ b/crates/store/re_types/src/datatypes/plane3d_ext.rs @@ -11,11 +11,13 @@ impl Plane3D { pub const XY: Self = Self([0.0, 0.0, 1.0, 0.0]); /// The normal of the plane (unnormalized if the plane is unnormalized). + #[inline] pub const fn normal(&self) -> super::Vec3D { super::Vec3D([self.0[0], self.0[1], self.0[2]]) } /// The distance of the plane from the origin (in multiples of the normal if the normal is unnormalized). + #[inline] pub const fn distance(&self) -> f32 { self.0[3] } @@ -23,6 +25,7 @@ impl Plane3D { /// Create a new plane from a normal and distance. /// /// The plane will not be normalized upon creation. + #[inline] pub fn new(normal: impl Into, d: f32) -> Self { let normal = normal.into(); Self([normal.0[0], normal.0[1], normal.0[2], d]) diff --git a/crates/viewer/re_component_ui/src/datatype_uis/vec.rs b/crates/viewer/re_component_ui/src/datatype_uis/vec.rs index b28bf039d3f6..a0e7fe2eb4df 100644 --- a/crates/viewer/re_component_ui/src/datatype_uis/vec.rs +++ b/crates/viewer/re_component_ui/src/datatype_uis/vec.rs @@ -12,7 +12,31 @@ pub fn edit_or_view_vec3d( MaybeMutRef::Ref(value) => MaybeMutRef::Ref(value), MaybeMutRef::MutRef(value) => MaybeMutRef::MutRef(value), }; - edit_or_view_vec3d_raw(ui, &mut value) + edit_or_view_vec3d_raw_immutable(ui, &mut value) +} + +// TODO(#6743): Since overrides are not yet taken into account, editing this value has no effect. +//MaybeMutRef::MutRef(value) => MaybeMutRef::MutRef(&mut value[i]), +fn edit_or_view_vec3d_raw_immutable( + ui: &mut egui::Ui, + value: &mut MaybeMutRef<'_, datatypes::Vec3D>, +) -> egui::Response { + edit_or_view_vector_component_immutable(ui, value, 0) + | edit_or_view_vector_component_immutable(ui, value, 1) + | edit_or_view_vector_component_immutable(ui, value, 2) +} + +fn edit_or_view_vector_component_immutable( + ui: &mut egui::Ui, + value: &mut MaybeMutRef<'_, datatypes::Vec3D>, + i: usize, +) -> egui::Response { + let mut value: MaybeMutRef<'_, f32> = match value { + MaybeMutRef::Ref(value) => MaybeMutRef::Ref(&value[i]), + + MaybeMutRef::MutRef(value) => MaybeMutRef::Ref(&value[i]), + }; + edit_f32_float_raw(ui, &mut value, f32::MIN..=f32::MAX) } pub fn edit_or_view_vec3d_raw( @@ -31,9 +55,7 @@ fn edit_or_view_vector_component( ) -> egui::Response { let mut value: MaybeMutRef<'_, f32> = match value { MaybeMutRef::Ref(value) => MaybeMutRef::Ref(&value[i]), - // TODO(#6743): Since overrides are not yet taken into account, editing this value has no effect. - //MaybeMutRef::MutRef(value) => MaybeMutRef::MutRef(&mut value[i]), - MaybeMutRef::MutRef(value) => MaybeMutRef::Ref(&value[i]), + MaybeMutRef::MutRef(value) => MaybeMutRef::MutRef(&mut value[i]), }; edit_f32_float_raw(ui, &mut value, f32::MIN..=f32::MAX) } diff --git a/crates/viewer/re_component_ui/src/lib.rs b/crates/viewer/re_component_ui/src/lib.rs index 59d49fcb7cb6..df5bbb282040 100644 --- a/crates/viewer/re_component_ui/src/lib.rs +++ b/crates/viewer/re_component_ui/src/lib.rs @@ -172,7 +172,8 @@ pub fn create_component_ui_registry() -> re_viewer_context::ComponentUiRegistry registry.add_singleline_edit_or_view(zoom_level::edit_zoom_level); - // TODO: add ui for plane + registry.add_singleline_edit_or_view(plane3d::edit_or_view_plane3d); + registry.add_multiline_edit_or_view(plane3d::multiline_edit_or_view_plane3d); registry } diff --git a/crates/viewer/re_component_ui/src/plane3d.rs b/crates/viewer/re_component_ui/src/plane3d.rs index 9e0433519c11..6d88db644de5 100644 --- a/crates/viewer/re_component_ui/src/plane3d.rs +++ b/crates/viewer/re_component_ui/src/plane3d.rs @@ -1,42 +1,162 @@ -use re_types::datatypes; +use re_types::{components, external::glam}; +use re_ui::UiExt as _; use re_viewer_context::MaybeMutRef; -use crate::datatype_uis::{edit_f32_float_raw, edit_or_view_vec3d_raw}; +use crate::{ + datatype_uis::{edit_f32_float_raw, edit_or_view_vec3d_raw}, + response_utils::response_with_changes_of_inner, +}; + +#[derive(PartialEq, Eq, Copy, Clone)] +enum AxisDirection { + PosX, + PosY, + PosZ, + NegX, + NegY, + NegZ, +} + +impl AxisDirection { + const VARIANTS: [Self; 6] = [ + Self::PosX, + Self::PosY, + Self::PosZ, + Self::NegX, + Self::NegY, + Self::NegZ, + ]; +} + +impl std::fmt::Display for AxisDirection { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::PosX => write!(f, "+X"), + Self::PosY => write!(f, "+Y"), + Self::PosZ => write!(f, "+Z"), + Self::NegX => write!(f, "-X"), + Self::NegY => write!(f, "-Y"), + Self::NegZ => write!(f, "-Z"), + } + } +} + +impl TryFrom for AxisDirection { + type Error = (); + + fn try_from(value: glam::Vec3) -> Result { + match value { + glam::Vec3::X => Ok(Self::PosX), + glam::Vec3::Y => Ok(Self::PosY), + glam::Vec3::Z => Ok(Self::PosZ), + glam::Vec3::NEG_X => Ok(Self::NegX), + glam::Vec3::NEG_Y => Ok(Self::NegY), + glam::Vec3::NEG_Z => Ok(Self::NegZ), + _ => Err(()), + } + } +} + +impl From for glam::Vec3 { + fn from(value: AxisDirection) -> Self { + match value { + AxisDirection::PosX => Self::X, + AxisDirection::PosY => Self::Y, + AxisDirection::PosZ => Self::Z, + AxisDirection::NegX => Self::NEG_X, + AxisDirection::NegY => Self::NEG_Y, + AxisDirection::NegZ => Self::NEG_Z, + } + } +} pub fn edit_or_view_plane3d( _ctx: &re_viewer_context::ViewerContext<'_>, ui: &mut egui::Ui, - value: &mut MaybeMutRef<'_, impl std::ops::DerefMut>, + value: &mut MaybeMutRef<'_, components::Plane3D>, ) -> egui::Response { - let mut value: MaybeMutRef<'_, datatypes::Plane3D> = match value { - MaybeMutRef::Ref(value) => MaybeMutRef::Ref(value), - MaybeMutRef::MutRef(value) => MaybeMutRef::MutRef(value), + let distance = value.distance(); + + ui.label("n"); + // Show simplified combobox if this is is axis aligned. + let normal_response = if let Ok(mut axis_dir) = + AxisDirection::try_from(glam::Vec3::from(value.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 MaybeMutRef::MutRef(value) = value { + **value = components::Plane3D::new(glam::Vec3::from(axis_dir), distance); + } + response + }), + ) + } else { + // Editing for arbitrary normals takes too much space here. + edit_or_view_vec3d_raw(ui, &mut MaybeMutRef::Ref(&value.normal())) + }; + + ui.label("d"); + let mut maybe_mut_distance = match value { + MaybeMutRef::Ref(value) => MaybeMutRef::Ref(&value.0 .0[3]), + MaybeMutRef::MutRef(value) => MaybeMutRef::MutRef(&mut value.0 .0[3]), }; - edit_or_view_plane3d_impl(ui, &mut value) + let distance_response = edit_f32_float_raw(ui, &mut maybe_mut_distance, f32::MIN..=f32::MAX); + + normal_response | distance_response } -fn edit_or_view_plane3d_impl( +pub fn multiline_edit_or_view_plane3d( + _ctx: &re_viewer_context::ViewerContext<'_>, ui: &mut egui::Ui, - value: &mut MaybeMutRef<'_, datatypes::Plane3D>, + value: &mut MaybeMutRef<'_, components::Plane3D>, ) -> egui::Response { - let mut normal = value.normal(); - let mut distance = value.distance(); - let (mut maybe_mut_normal, mut maybe_mutdistance) = match value { - MaybeMutRef::Ref(value) => (MaybeMutRef::Ref(&normal), MaybeMutRef::Ref(&distance)), - MaybeMutRef::MutRef(value) => ( - MaybeMutRef::MutRef(&mut normal), - MaybeMutRef::MutRef(&mut distance), - ), - }; + let mut any_edit = false; - ui.label("n"); - let normal_response = edit_or_view_vec3d_raw(ui, &mut maybe_mut_normal); - ui.label("d"); - let distance_response = edit_f32_float_raw(ui, &mut maybe_mutdistance, f32::MIN..=f32::MAX); + let response_normal = ui.list_item_flat_noninteractive( + re_ui::list_item::PropertyContent::new("Normal").value_fn(|ui, _| { + let mut normal = value.normal(); + let mut maybe_mut_normal = match value { + MaybeMutRef::Ref(_) => MaybeMutRef::Ref(&normal), + MaybeMutRef::MutRef(_) => MaybeMutRef::MutRef(&mut normal), + }; - if let MaybeMutRef::MutRef(value) = value { - **value = datatypes::Plane3D::new(normal, distance); - } + any_edit |= edit_or_view_vec3d_raw(ui, &mut maybe_mut_normal).changed(); + + if let MaybeMutRef::MutRef(value) = value { + **value = components::Plane3D::new(normal, value.distance()); + } + }), + ); - normal_response.union(distance_response) + let response_distance = ui.list_item_flat_noninteractive( + re_ui::list_item::PropertyContent::new("Distance").value_fn(|ui, _| { + let mut maybe_mut_distance = match value { + MaybeMutRef::Ref(value) => MaybeMutRef::Ref(&value.0 .0[3]), + MaybeMutRef::MutRef(value) => MaybeMutRef::MutRef(&mut value.0 .0[3]), + }; + + any_edit |= + edit_f32_float_raw(ui, &mut maybe_mut_distance, f32::MIN..=f32::MAX).changed(); + }), + ); + + let mut response = response_normal | response_distance; + if any_edit { + response.mark_changed(); + } + response } diff --git a/crates/viewer/re_space_view_spatial/src/view_3d_properties.rs b/crates/viewer/re_space_view_spatial/src/view_3d_properties.rs index bae1c97c94a3..304083171007 100644 --- a/crates/viewer/re_space_view_spatial/src/view_3d_properties.rs +++ b/crates/viewer/re_space_view_spatial/src/view_3d_properties.rs @@ -52,11 +52,7 @@ impl TypedComponentFallbackProvider for SpatialSpaceView3D { .state_3d .scene_view_coordinates .and_then(|view_coordinates| view_coordinates.up()) - .map_or(DEFAULT_PLANE, |up| match up.axis { - re_types::view_coordinates::Axis3::X => Plane3D::YZ, - re_types::view_coordinates::Axis3::Y => Plane3D::ZX, - re_types::view_coordinates::Axis3::Z => Plane3D::XY, - }) + .map_or(DEFAULT_PLANE, |up| Plane3D::new(up.as_vec3(), 0.0)) } } From 95ca76b624e75c7f0ec89cb82b1bb19244a8b2f8 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Tue, 3 Dec 2024 17:46:19 +0100 Subject: [PATCH 14/29] fix every color having an alpha channel picker --- crates/viewer/re_component_ui/src/color.rs | 5 +- .../re_space_view_spatial/src/view_3d.rs | 90 ++++++++++++++++++- 2 files changed, 89 insertions(+), 6 deletions(-) diff --git a/crates/viewer/re_component_ui/src/color.rs b/crates/viewer/re_component_ui/src/color.rs index 09114a162253..48392540adf1 100644 --- a/crates/viewer/re_component_ui/src/color.rs +++ b/crates/viewer/re_component_ui/src/color.rs @@ -19,8 +19,9 @@ fn edit_rgba32_impl(ui: &mut egui::Ui, color: &mut MaybeMutRef<'_, Rgba32>) -> e let response = egui::color_picker::color_edit_button_srgba( ui, &mut edit_color, - // TODO(#1611): Most of the time this doesn't do anything. Would be great to distinguish that. - egui::color_picker::Alpha::OnlyBlend, + // TODO(#1611): No transparency supported right now. + // Once we do we probably need to be more explicit about the component semantics. + egui::color_picker::Alpha::Opaque, ); *color = edit_color.into(); response diff --git a/crates/viewer/re_space_view_spatial/src/view_3d.rs b/crates/viewer/re_space_view_spatial/src/view_3d.rs index 6ebb771a3b05..34fa52b4e617 100644 --- a/crates/viewer/re_space_view_spatial/src/view_3d.rs +++ b/crates/viewer/re_space_view_spatial/src/view_3d.rs @@ -6,12 +6,11 @@ use re_entity_db::EntityDb; use re_log_types::EntityPath; use re_space_view::view_property_ui; use re_types::blueprint::archetypes::LineGrid3D; -use re_types::View; use re_types::{ blueprint::archetypes::Background, components::ViewCoordinates, Component, - SpaceViewClassIdentifier, + SpaceViewClassIdentifier, View, }; -use re_ui::UiExt as _; +use re_ui::{list_item, UiExt as _}; use re_viewer_context::{ ApplicableEntities, IdentifiedViewSystem, IndicatedEntities, PerVisualizer, RecommendedSpaceView, SmallVisualizerSet, SpaceViewClass, SpaceViewClassRegistryError, @@ -19,6 +18,7 @@ use re_viewer_context::{ SpaceViewSystemExecutionError, ViewQuery, ViewSystemIdentifier, ViewerContext, VisualizableEntities, VisualizableFilterContext, }; +use re_viewport_blueprint::ViewProperty; use crate::visualizers::{AxisLengthDetector, CamerasVisualizer, Transform3DArrowsVisualizer}; use crate::{ @@ -422,7 +422,8 @@ impl SpaceViewClass for SpatialSpaceView3D { re_ui::list_item::list_item_scope(ui, "spatial_view3d_selection_ui", |ui| { view_property_ui::(ctx, ui, view_id, self, state); - view_property_ui::(ctx, ui, view_id, self, state); + //view_property_ui::(ctx, ui, view_id, self, state); + view_property_ui_grid3d(ctx, ui, view_id, self, state); }); Ok(()) @@ -445,3 +446,84 @@ impl SpaceViewClass for SpatialSpaceView3D { self.view_3d(ctx, ui, state, query, system_output) } } + +fn view_property_ui_grid3d( + ctx: &ViewerContext<'_>, + ui: &mut egui::Ui, + view_id: SpaceViewId, + fallback_provider: &dyn re_viewer_context::ComponentFallbackProvider, + view_state: &dyn SpaceViewState, +) { + let property = ViewProperty::from_archetype::( + ctx.blueprint_db(), + ctx.blueprint_query, + view_id, + ); + let Some(reflection) = ctx.reflection.archetypes.get(&property.archetype_name) else { + ui.error_label(format!( + "Missing reflection data for archetype {:?}.", + property.archetype_name + )); + return; + }; + + let query_ctx = property.query_context(ctx, view_state); + let sub_prop_ui = |ui: &mut egui::Ui| { + for field in &reflection.fields { + // TODO(#1611): The color picker for the color component doesn't show alpha values so far since alpha is almost never supported. + // Here however, we need that alpha color picker! + if field.component_name == re_types::components::Color::name() { + re_space_view::view_property_component_ui_custom( + &query_ctx, + ui, + &property, + field.display_name, + field, + &|ui| { + let Ok(color) = property + .component_or_fallback::( + ctx, + fallback_provider, + view_state, + ) + else { + ui.error_label("Failed to query color component"); + return; + }; + let mut edit_color = egui::Color32::from(*color); + if egui::color_picker::color_edit_button_srgba( + ui, + &mut edit_color, + egui::color_picker::Alpha::OnlyBlend, + ) + .changed() + { + let color = re_types::components::Color::from(edit_color); + property.save_blueprint_component(ctx, &[color]); + } + }, + None, // No multiline editor. + ); + } else { + re_space_view::view_property_component_ui( + &query_ctx, + ui, + &property, + field.display_name, + field, + fallback_provider, + ); + } + } + }; + + ui.list_item() + .interactive(false) + .show_hierarchical_with_children( + ui, + ui.make_persistent_id(property.archetype_name.full_name()), + true, + list_item::LabelContent::new(reflection.display_name), + sub_prop_ui, + ); +} From e95b715a4be7accb2d1f3b64b7faa620b1c11148 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Tue, 3 Dec 2024 17:48:36 +0100 Subject: [PATCH 15/29] remove wiki link for hesse normal form --- crates/store/re_types/definitions/rerun/components/plane3d.fbs | 2 +- crates/store/re_types/definitions/rerun/datatypes/plane3d.fbs | 2 +- crates/store/re_types/src/components/plane3d.rs | 2 +- crates/store/re_types/src/datatypes/plane3d.rs | 2 +- crates/viewer/re_component_ui/src/plane3d.rs | 2 +- crates/viewer/re_viewer/src/reflection/mod.rs | 2 +- docs/content/reference/types/components/plane3d.md | 2 +- docs/content/reference/types/datatypes/plane3d.md | 2 +- rerun_cpp/src/rerun/components/plane3d.hpp | 2 +- rerun_cpp/src/rerun/datatypes/plane3d.hpp | 2 +- rerun_py/rerun_sdk/rerun/components/plane3d.py | 2 +- rerun_py/rerun_sdk/rerun/datatypes/plane3d.py | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/crates/store/re_types/definitions/rerun/components/plane3d.fbs b/crates/store/re_types/definitions/rerun/components/plane3d.fbs index c5b61526d719..db24ec337779 100644 --- a/crates/store/re_types/definitions/rerun/components/plane3d.fbs +++ b/crates/store/re_types/definitions/rerun/components/plane3d.fbs @@ -3,7 +3,7 @@ namespace rerun.components; /// An infinite 3D plane represented by a unit normal vector and a distance. /// /// Any point P on the plane fulfills the equation `dot(xyz, P) - d = 0`, where `xyz` is the plane's normal and `d` the distance. -/// This representation is also known as the Hesse normal form, see https://en.wikipedia.org/wiki/Hesse_normal_form +/// This representation is also known as the Hesse normal form. /// /// Note: although the normal will be passed through to the /// datastore as provided, when used in the Viewer, planes will always be normalized. diff --git a/crates/store/re_types/definitions/rerun/datatypes/plane3d.fbs b/crates/store/re_types/definitions/rerun/datatypes/plane3d.fbs index 863a8ad1b911..4d85ef4103d2 100644 --- a/crates/store/re_types/definitions/rerun/datatypes/plane3d.fbs +++ b/crates/store/re_types/definitions/rerun/datatypes/plane3d.fbs @@ -3,7 +3,7 @@ namespace rerun.datatypes; /// An infinite 3D plane represented by a unit normal vector and a distance. /// /// Any point P on the plane fulfills the equation `dot(xyz, P) - d = 0`, where `xyz` is the plane's normal and `d` the distance. -/// This representation is also known as the Hesse normal form, see https://en.wikipedia.org/wiki/Hesse_normal_form +/// This representation is also known as the Hesse normal form. /// /// Note: although the normal will be passed through to the /// datastore as provided, when used in the Viewer, planes will always be normalized. diff --git a/crates/store/re_types/src/components/plane3d.rs b/crates/store/re_types/src/components/plane3d.rs index 6a66c38afa7f..da74eca48e94 100644 --- a/crates/store/re_types/src/components/plane3d.rs +++ b/crates/store/re_types/src/components/plane3d.rs @@ -21,7 +21,7 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; /// **Component**: An infinite 3D plane represented by a unit normal vector and a distance. /// /// Any point P on the plane fulfills the equation `dot(xyz, P) - d = 0`, where `xyz` is the plane's normal and `d` the distance. -/// This representation is also known as the Hesse normal form, see https://en.wikipedia.org/wiki/Hesse_normal_form +/// This representation is also known as the Hesse normal form. /// /// Note: although the normal will be passed through to the /// datastore as provided, when used in the Viewer, planes will always be normalized. diff --git a/crates/store/re_types/src/datatypes/plane3d.rs b/crates/store/re_types/src/datatypes/plane3d.rs index c55eed270a83..e12fd4a2c1e5 100644 --- a/crates/store/re_types/src/datatypes/plane3d.rs +++ b/crates/store/re_types/src/datatypes/plane3d.rs @@ -21,7 +21,7 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; /// **Datatype**: An infinite 3D plane represented by a unit normal vector and a distance. /// /// Any point P on the plane fulfills the equation `dot(xyz, P) - d = 0`, where `xyz` is the plane's normal and `d` the distance. -/// This representation is also known as the Hesse normal form, see https://en.wikipedia.org/wiki/Hesse_normal_form +/// This representation is also known as the Hesse normal form. /// /// Note: although the normal will be passed through to the /// datastore as provided, when used in the Viewer, planes will always be normalized. diff --git a/crates/viewer/re_component_ui/src/plane3d.rs b/crates/viewer/re_component_ui/src/plane3d.rs index 6d88db644de5..d2870fdbc7a1 100644 --- a/crates/viewer/re_component_ui/src/plane3d.rs +++ b/crates/viewer/re_component_ui/src/plane3d.rs @@ -78,7 +78,7 @@ pub fn edit_or_view_plane3d( let distance = value.distance(); ui.label("n"); - // Show simplified combobox if this is is axis aligned. + // Show simplified combobox if this is axis aligned. let normal_response = if let Ok(mut axis_dir) = AxisDirection::try_from(glam::Vec3::from(value.normal())) { diff --git a/crates/viewer/re_viewer/src/reflection/mod.rs b/crates/viewer/re_viewer/src/reflection/mod.rs index 6a6ce1a73c7c..8c4e731e91fc 100644 --- a/crates/viewer/re_viewer/src/reflection/mod.rs +++ b/crates/viewer/re_viewer/src/reflection/mod.rs @@ -619,7 +619,7 @@ fn generate_component_reflection() -> Result::name(), ComponentReflection { - docstring_md: "An infinite 3D plane represented by a unit normal vector and a distance.\n\nAny point P on the plane fulfills the equation `dot(xyz, P) - d = 0`, where `xyz` is the plane's normal and `d` the distance.\nThis representation is also known as the Hesse normal form, see https://en.wikipedia.org/wiki/Hesse_normal_form\n\nNote: although the normal will be passed through to the\ndatastore as provided, when used in the Viewer, planes will always be normalized.\nI.e. the plane with xyz = (2, 0, 0), d = 1 is equivalent to xyz = (1, 0, 0), d = 0.5", + docstring_md: "An infinite 3D plane represented by a unit normal vector and a distance.\n\nAny point P on the plane fulfills the equation `dot(xyz, P) - d = 0`, where `xyz` is the plane's normal and `d` the distance.\nThis representation is also known as the Hesse normal form.\n\nNote: although the normal will be passed through to the\ndatastore as provided, when used in the Viewer, planes will always be normalized.\nI.e. the plane with xyz = (2, 0, 0), d = 1 is equivalent to xyz = (1, 0, 0), d = 0.5", custom_placeholder: None, datatype: Plane3D::arrow2_datatype(), }, diff --git a/docs/content/reference/types/components/plane3d.md b/docs/content/reference/types/components/plane3d.md index 9a2388f5639b..5ecfc6223e38 100644 --- a/docs/content/reference/types/components/plane3d.md +++ b/docs/content/reference/types/components/plane3d.md @@ -6,7 +6,7 @@ title: "Plane3D" An infinite 3D plane represented by a unit normal vector and a distance. Any point P on the plane fulfills the equation `dot(xyz, P) - d = 0`, where `xyz` is the plane's normal and `d` the distance. -This representation is also known as the Hesse normal form, see https://en.wikipedia.org/wiki/Hesse_normal_form +This representation is also known as the Hesse normal form. Note: although the normal will be passed through to the datastore as provided, when used in the Viewer, planes will always be normalized. diff --git a/docs/content/reference/types/datatypes/plane3d.md b/docs/content/reference/types/datatypes/plane3d.md index 45fb072ce74a..38eb178734b1 100644 --- a/docs/content/reference/types/datatypes/plane3d.md +++ b/docs/content/reference/types/datatypes/plane3d.md @@ -6,7 +6,7 @@ title: "Plane3D" An infinite 3D plane represented by a unit normal vector and a distance. Any point P on the plane fulfills the equation `dot(xyz, P) - d = 0`, where `xyz` is the plane's normal and `d` the distance. -This representation is also known as the Hesse normal form, see https://en.wikipedia.org/wiki/Hesse_normal_form +This representation is also known as the Hesse normal form. Note: although the normal will be passed through to the datastore as provided, when used in the Viewer, planes will always be normalized. diff --git a/rerun_cpp/src/rerun/components/plane3d.hpp b/rerun_cpp/src/rerun/components/plane3d.hpp index fbc19a018484..77308aad034c 100644 --- a/rerun_cpp/src/rerun/components/plane3d.hpp +++ b/rerun_cpp/src/rerun/components/plane3d.hpp @@ -13,7 +13,7 @@ namespace rerun::components { /// **Component**: An infinite 3D plane represented by a unit normal vector and a distance. /// /// Any point P on the plane fulfills the equation `dot(xyz, P) - d = 0`, where `xyz` is the plane's normal and `d` the distance. - /// This representation is also known as the Hesse normal form, see https://en.wikipedia.org/wiki/Hesse_normal_form + /// This representation is also known as the Hesse normal form. /// /// Note: although the normal will be passed through to the /// datastore as provided, when used in the Viewer, planes will always be normalized. diff --git a/rerun_cpp/src/rerun/datatypes/plane3d.hpp b/rerun_cpp/src/rerun/datatypes/plane3d.hpp index 5d66df54a923..4e6797245324 100644 --- a/rerun_cpp/src/rerun/datatypes/plane3d.hpp +++ b/rerun_cpp/src/rerun/datatypes/plane3d.hpp @@ -19,7 +19,7 @@ namespace rerun::datatypes { /// **Datatype**: An infinite 3D plane represented by a unit normal vector and a distance. /// /// Any point P on the plane fulfills the equation `dot(xyz, P) - d = 0`, where `xyz` is the plane's normal and `d` the distance. - /// This representation is also known as the Hesse normal form, see https://en.wikipedia.org/wiki/Hesse_normal_form + /// This representation is also known as the Hesse normal form. /// /// Note: although the normal will be passed through to the /// datastore as provided, when used in the Viewer, planes will always be normalized. diff --git a/rerun_py/rerun_sdk/rerun/components/plane3d.py b/rerun_py/rerun_sdk/rerun/components/plane3d.py index 56699ca3186f..72a6b42517ad 100644 --- a/rerun_py/rerun_sdk/rerun/components/plane3d.py +++ b/rerun_py/rerun_sdk/rerun/components/plane3d.py @@ -19,7 +19,7 @@ class Plane3D(datatypes.Plane3D, ComponentMixin): **Component**: An infinite 3D plane represented by a unit normal vector and a distance. Any point P on the plane fulfills the equation `dot(xyz, P) - d = 0`, where `xyz` is the plane's normal and `d` the distance. - This representation is also known as the Hesse normal form, see https://en.wikipedia.org/wiki/Hesse_normal_form + This representation is also known as the Hesse normal form. Note: although the normal will be passed through to the datastore as provided, when used in the Viewer, planes will always be normalized. diff --git a/rerun_py/rerun_sdk/rerun/datatypes/plane3d.py b/rerun_py/rerun_sdk/rerun/datatypes/plane3d.py index c81819123838..0c2f818194cd 100644 --- a/rerun_py/rerun_sdk/rerun/datatypes/plane3d.py +++ b/rerun_py/rerun_sdk/rerun/datatypes/plane3d.py @@ -28,7 +28,7 @@ class Plane3D: **Datatype**: An infinite 3D plane represented by a unit normal vector and a distance. Any point P on the plane fulfills the equation `dot(xyz, P) - d = 0`, where `xyz` is the plane's normal and `d` the distance. - This representation is also known as the Hesse normal form, see https://en.wikipedia.org/wiki/Hesse_normal_form + This representation is also known as the Hesse normal form. Note: although the normal will be passed through to the datastore as provided, when used in the Viewer, planes will always be normalized. From 48230d9ee847251faf5b079833c3779a68767acc Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Tue, 3 Dec 2024 17:49:43 +0100 Subject: [PATCH 16/29] fix missing unreleased markers --- .../re_types/definitions/rerun/components/plane3d.fbs | 1 + .../re_types/definitions/rerun/datatypes/plane3d.fbs | 1 + docs/content/reference/types/components/plane3d.md | 6 +++--- docs/content/reference/types/datatypes/plane3d.md | 8 ++++---- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/crates/store/re_types/definitions/rerun/components/plane3d.fbs b/crates/store/re_types/definitions/rerun/components/plane3d.fbs index db24ec337779..9ec3fd3d147c 100644 --- a/crates/store/re_types/definitions/rerun/components/plane3d.fbs +++ b/crates/store/re_types/definitions/rerun/components/plane3d.fbs @@ -9,6 +9,7 @@ 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/datatypes/plane3d.fbs b/crates/store/re_types/definitions/rerun/datatypes/plane3d.fbs index 4d85ef4103d2..2d02dbfe1515 100644 --- a/crates/store/re_types/definitions/rerun/datatypes/plane3d.fbs +++ b/crates/store/re_types/definitions/rerun/datatypes/plane3d.fbs @@ -9,6 +9,7 @@ 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/docs/content/reference/types/components/plane3d.md b/docs/content/reference/types/components/plane3d.md index 5ecfc6223e38..320375107cd6 100644 --- a/docs/content/reference/types/components/plane3d.md +++ b/docs/content/reference/types/components/plane3d.md @@ -22,8 +22,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) - * 🐍 [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) + * 🌊 [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) diff --git a/docs/content/reference/types/datatypes/plane3d.md b/docs/content/reference/types/datatypes/plane3d.md index 38eb178734b1..b74bf18af515 100644 --- a/docs/content/reference/types/datatypes/plane3d.md +++ b/docs/content/reference/types/datatypes/plane3d.md @@ -19,11 +19,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) - * 🐍 [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) + * 🌊 [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) ## Used by -* [`Plane3D`](../components/plane3d.md) +* [`Plane3D`](../components/plane3d.md?speculative-link) From 6706a928a544d85521224c2f33ff2188435dba8b Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Tue, 3 Dec 2024 17:51:15 +0100 Subject: [PATCH 17/29] add plane to all components check --- tests/python/release_checklist/check_all_components_ui.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/python/release_checklist/check_all_components_ui.py b/tests/python/release_checklist/check_all_components_ui.py index cd9cab6cfecc..e9f484296bcd 100644 --- a/tests/python/release_checklist/check_all_components_ui.py +++ b/tests/python/release_checklist/check_all_components_ui.py @@ -184,6 +184,7 @@ def alternatives(self) -> list[Any] | None: "NameBatch": TestCase(batch=["Hello World", "Foo Bar", "Baz Qux"]), "OpacityBatch": TestCase(0.5), "PinholeProjectionBatch": TestCase([(0, 1, 2), (3, 4, 5), (6, 7, 8)]), + "Plane3DBatch": TestCase(rr.datatypes.Plane3D(xyzd=(1, 2, 3, 4))), "PoseRotationAxisAngleBatch": TestCase( rr.datatypes.RotationAxisAngle(axis=(1, 0, 0), angle=rr.datatypes.Angle(rad=math.pi)) ), From dec853d53aa2fd55ce4b95c665a12d9a5da7b24c Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Tue, 3 Dec 2024 18:15:59 +0100 Subject: [PATCH 18/29] remove RadiusUi again in favor of StrokeWidth add 'pt' suffix for ui radii --- .../blueprint/archetypes/line_grid_3d.fbs | 4 +- .../rerun/blueprint/components.fbs | 1 - .../rerun/blueprint/components/ui_radius.fbs | 11 -- .../src/blueprint/archetypes/line_grid3d.rs | 45 ++++--- .../src/blueprint/components/.gitattributes | 1 - .../re_types/src/blueprint/components/mod.rs | 2 - .../src/blueprint/components/ui_radius.rs | 116 ------------------ .../src/datatype_uis/float_drag.rs | 32 ++++- .../re_component_ui/src/datatype_uis/mod.rs | 2 +- .../re_component_ui/src/datatype_uis/vec.rs | 4 +- crates/viewer/re_component_ui/src/lib.rs | 12 +- crates/viewer/re_component_ui/src/plane3d.rs | 5 +- .../viewer/re_space_view_spatial/src/ui_3d.rs | 6 +- .../src/view_3d_properties.rs | 17 +-- .../src/blueprint/validation_gen/mod.rs | 2 - crates/viewer/re_viewer/src/reflection/mod.rs | 14 +-- .../reference/types/views/spatial3d_view.md | 2 +- .../blueprint/archetypes/line_grid3d.cpp | 4 +- .../blueprint/archetypes/line_grid3d.hpp | 12 +- rerun_cpp/src/rerun/blueprint/components.hpp | 1 - .../rerun/blueprint/components/.gitattributes | 1 - .../rerun/blueprint/components/ui_radius.hpp | 74 ----------- .../rerun/blueprint/archetypes/line_grid3d.py | 16 +-- .../rerun/blueprint/components/.gitattributes | 1 - .../rerun/blueprint/components/__init__.py | 3 - .../rerun/blueprint/components/ui_radius.py | 32 ----- 26 files changed, 91 insertions(+), 329 deletions(-) delete mode 100644 crates/store/re_types/definitions/rerun/blueprint/components/ui_radius.fbs delete mode 100644 crates/store/re_types/src/blueprint/components/ui_radius.rs delete mode 100644 rerun_cpp/src/rerun/blueprint/components/ui_radius.hpp delete mode 100644 rerun_py/rerun_sdk/rerun/blueprint/components/ui_radius.py diff --git a/crates/store/re_types/definitions/rerun/blueprint/archetypes/line_grid_3d.fbs b/crates/store/re_types/definitions/rerun/blueprint/archetypes/line_grid_3d.fbs index e1d1094056da..11e6ac802380 100644 --- a/crates/store/re_types/definitions/rerun/blueprint/archetypes/line_grid_3d.fbs +++ b/crates/store/re_types/definitions/rerun/blueprint/archetypes/line_grid_3d.fbs @@ -19,8 +19,8 @@ table LineGrid3D ( /// How thick the lines should be in ui units. /// - /// Default is 0.5 ui unit. - line_radius: rerun.blueprint.components.UiRadius ("attr.rerun.component_optional", nullable, order: 5000); + /// Default is 1.0 ui unit. + stroke_width: rerun.components.StrokeWidth ("attr.rerun.component_optional", nullable, order: 5000); /// Color used for the grid. /// diff --git a/crates/store/re_types/definitions/rerun/blueprint/components.fbs b/crates/store/re_types/definitions/rerun/blueprint/components.fbs index 46c186e893e5..1ee15c8acbe8 100644 --- a/crates/store/re_types/definitions/rerun/blueprint/components.fbs +++ b/crates/store/re_types/definitions/rerun/blueprint/components.fbs @@ -27,7 +27,6 @@ include "./components/space_view_maximized.fbs"; include "./components/space_view_origin.fbs"; include "./components/tensor_dimension_index_slider.fbs"; include "./components/timeline_name.fbs"; -include "./components/ui_radius.fbs"; include "./components/view_fit.fbs"; include "./components/viewer_recommendation_hash.fbs"; include "./components/visible.fbs"; diff --git a/crates/store/re_types/definitions/rerun/blueprint/components/ui_radius.fbs b/crates/store/re_types/definitions/rerun/blueprint/components/ui_radius.fbs deleted file mode 100644 index f2c977aca809..000000000000 --- a/crates/store/re_types/definitions/rerun/blueprint/components/ui_radius.fbs +++ /dev/null @@ -1,11 +0,0 @@ -namespace rerun.blueprint.components; - -/// Like `Radius`, but in always in ui units. -table UiRadius ( - "attr.python.aliases": "float", - "attr.python.array_aliases": "npt.ArrayLike", - "attr.rerun.scope": "blueprint" -) { - /// Radius in ui units. - radius: rerun.datatypes.Float32 (order: 100); -} diff --git a/crates/store/re_types/src/blueprint/archetypes/line_grid3d.rs b/crates/store/re_types/src/blueprint/archetypes/line_grid3d.rs index 1ddec38f1f9d..755bc4a5b995 100644 --- a/crates/store/re_types/src/blueprint/archetypes/line_grid3d.rs +++ b/crates/store/re_types/src/blueprint/archetypes/line_grid3d.rs @@ -36,8 +36,8 @@ pub struct LineGrid3D { /// How thick the lines should be in ui units. /// - /// Default is 0.5 ui unit. - pub line_radius: Option, + /// Default is 1.0 ui unit. + pub stroke_width: Option, /// Color used for the grid. /// @@ -52,7 +52,7 @@ impl ::re_types_core::SizeBytes for LineGrid3D { self.visible.heap_size_bytes() + self.spacing.heap_size_bytes() + self.plane.heap_size_bytes() - + self.line_radius.heap_size_bytes() + + self.stroke_width.heap_size_bytes() + self.color.heap_size_bytes() } @@ -61,7 +61,7 @@ impl ::re_types_core::SizeBytes for LineGrid3D { >::is_pod() && >::is_pod() && >::is_pod() - && >::is_pod() + && >::is_pod() && >::is_pod() } } @@ -78,7 +78,7 @@ static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentName; 5usize]> = "rerun.blueprint.components.Visible".into(), "rerun.blueprint.components.GridSpacing".into(), "rerun.components.Plane3D".into(), - "rerun.blueprint.components.UiRadius".into(), + "rerun.components.StrokeWidth".into(), "rerun.components.Color".into(), ] }); @@ -90,7 +90,7 @@ static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentName; 6usize]> = "rerun.blueprint.components.Visible".into(), "rerun.blueprint.components.GridSpacing".into(), "rerun.components.Plane3D".into(), - "rerun.blueprint.components.UiRadius".into(), + "rerun.components.StrokeWidth".into(), "rerun.components.Color".into(), ] }); @@ -181,16 +181,15 @@ impl ::re_types_core::Archetype for LineGrid3D { } else { None }; - let line_radius = - if let Some(array) = arrays_by_name.get("rerun.blueprint.components.UiRadius") { - ::from_arrow2_opt(&**array) - .with_context("rerun.blueprint.archetypes.LineGrid3D#line_radius")? - .into_iter() - .next() - .flatten() - } else { - None - }; + let stroke_width = if let Some(array) = arrays_by_name.get("rerun.components.StrokeWidth") { + ::from_arrow2_opt(&**array) + .with_context("rerun.blueprint.archetypes.LineGrid3D#stroke_width")? + .into_iter() + .next() + .flatten() + } else { + None + }; let color = if let Some(array) = arrays_by_name.get("rerun.components.Color") { ::from_arrow2_opt(&**array) .with_context("rerun.blueprint.archetypes.LineGrid3D#color")? @@ -204,7 +203,7 @@ impl ::re_types_core::Archetype for LineGrid3D { visible, spacing, plane, - line_radius, + stroke_width, color, }) } @@ -225,7 +224,7 @@ impl ::re_types_core::AsComponents for LineGrid3D { self.plane .as_ref() .map(|comp| (comp as &dyn ComponentBatch).into()), - self.line_radius + self.stroke_width .as_ref() .map(|comp| (comp as &dyn ComponentBatch).into()), self.color @@ -248,7 +247,7 @@ impl LineGrid3D { visible: None, spacing: None, plane: None, - line_radius: None, + stroke_width: None, color: None, } } @@ -286,13 +285,13 @@ impl LineGrid3D { /// How thick the lines should be in ui units. /// - /// Default is 0.5 ui unit. + /// Default is 1.0 ui unit. #[inline] - pub fn with_line_radius( + pub fn with_stroke_width( mut self, - line_radius: impl Into, + stroke_width: impl Into, ) -> Self { - self.line_radius = Some(line_radius.into()); + self.stroke_width = Some(stroke_width.into()); self } diff --git a/crates/store/re_types/src/blueprint/components/.gitattributes b/crates/store/re_types/src/blueprint/components/.gitattributes index d57e8c893983..238359328a19 100644 --- a/crates/store/re_types/src/blueprint/components/.gitattributes +++ b/crates/store/re_types/src/blueprint/components/.gitattributes @@ -23,7 +23,6 @@ space_view_class.rs linguist-generated=true space_view_origin.rs linguist-generated=true tensor_dimension_index_slider.rs linguist-generated=true timeline_name.rs linguist-generated=true -ui_radius.rs linguist-generated=true view_fit.rs linguist-generated=true viewer_recommendation_hash.rs linguist-generated=true visible.rs linguist-generated=true diff --git a/crates/store/re_types/src/blueprint/components/mod.rs b/crates/store/re_types/src/blueprint/components/mod.rs index d564f791a1e5..ca655d4e56b3 100644 --- a/crates/store/re_types/src/blueprint/components/mod.rs +++ b/crates/store/re_types/src/blueprint/components/mod.rs @@ -32,7 +32,6 @@ mod tensor_dimension_index_slider; mod tensor_dimension_index_slider_ext; mod timeline_name; mod timeline_name_ext; -mod ui_radius; mod view_fit; mod viewer_recommendation_hash; mod viewer_recommendation_hash_ext; @@ -64,7 +63,6 @@ pub use self::space_view_class::SpaceViewClass; pub use self::space_view_origin::SpaceViewOrigin; pub use self::tensor_dimension_index_slider::TensorDimensionIndexSlider; pub use self::timeline_name::TimelineName; -pub use self::ui_radius::UiRadius; pub use self::view_fit::ViewFit; pub use self::viewer_recommendation_hash::ViewerRecommendationHash; pub use self::visible::Visible; diff --git a/crates/store/re_types/src/blueprint/components/ui_radius.rs b/crates/store/re_types/src/blueprint/components/ui_radius.rs deleted file mode 100644 index a6b9ba7b9604..000000000000 --- a/crates/store/re_types/src/blueprint/components/ui_radius.rs +++ /dev/null @@ -1,116 +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/blueprint/components/ui_radius.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::ComponentName; -use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, MaybeOwnedComponentBatch}; -use ::re_types_core::{DeserializationError, DeserializationResult}; - -/// **Component**: Like `Radius`, but in always in ui units. -#[derive(Clone, Debug)] -pub struct UiRadius( - /// Radius in ui units. - pub crate::datatypes::Float32, -); - -impl ::re_types_core::SizeBytes for UiRadius { - #[inline] - fn heap_size_bytes(&self) -> u64 { - self.0.heap_size_bytes() - } - - #[inline] - fn is_pod() -> bool { - ::is_pod() - } -} - -impl> From for UiRadius { - fn from(v: T) -> Self { - Self(v.into()) - } -} - -impl std::borrow::Borrow for UiRadius { - #[inline] - fn borrow(&self) -> &crate::datatypes::Float32 { - &self.0 - } -} - -impl std::ops::Deref for UiRadius { - type Target = crate::datatypes::Float32; - - #[inline] - fn deref(&self) -> &crate::datatypes::Float32 { - &self.0 - } -} - -impl std::ops::DerefMut for UiRadius { - #[inline] - fn deref_mut(&mut self) -> &mut crate::datatypes::Float32 { - &mut self.0 - } -} - -::re_types_core::macros::impl_into_cow!(UiRadius); - -impl ::re_types_core::Loggable for UiRadius { - #[inline] - fn arrow_datatype() -> arrow::datatypes::DataType { - crate::datatypes::Float32::arrow_datatype() - } - - fn to_arrow_opt<'a>( - data: impl IntoIterator>>>, - ) -> SerializationResult - where - Self: Clone + 'a, - { - crate::datatypes::Float32::to_arrow_opt(data.into_iter().map(|datum| { - datum.map(|datum| match datum.into() { - ::std::borrow::Cow::Borrowed(datum) => ::std::borrow::Cow::Borrowed(&datum.0), - ::std::borrow::Cow::Owned(datum) => ::std::borrow::Cow::Owned(datum.0), - }) - })) - } - - fn from_arrow2_opt( - arrow_data: &dyn arrow2::array::Array, - ) -> DeserializationResult>> - where - Self: Sized, - { - crate::datatypes::Float32::from_arrow2_opt(arrow_data) - .map(|v| v.into_iter().map(|v| v.map(Self)).collect()) - } - - #[inline] - fn from_arrow2(arrow_data: &dyn arrow2::array::Array) -> DeserializationResult> - where - Self: Sized, - { - crate::datatypes::Float32::from_arrow2(arrow_data) - .map(|v| v.into_iter().map(Self).collect()) - } -} - -impl ::re_types_core::Component for UiRadius { - #[inline] - fn name() -> ComponentName { - "rerun.blueprint.components.UiRadius".into() - } -} diff --git a/crates/viewer/re_component_ui/src/datatype_uis/float_drag.rs b/crates/viewer/re_component_ui/src/datatype_uis/float_drag.rs index 7b3b2f970e3a..b9aa5fa87b9b 100644 --- a/crates/viewer/re_component_ui/src/datatype_uis/float_drag.rs +++ b/crates/viewer/re_component_ui/src/datatype_uis/float_drag.rs @@ -6,15 +6,34 @@ use re_viewer_context::MaybeMutRef; /// Generic editor for a [`re_types::datatypes::Float32`] value from zero to max float. pub fn edit_f32_zero_to_max( + ctx: &re_viewer_context::ViewerContext<'_>, + ui: &mut egui::Ui, + value: &mut MaybeMutRef<'_, impl std::ops::DerefMut>, +) -> egui::Response { + edit_f32_zero_to_max_with_suffix(ctx, ui, value, "") +} + +/// Generic editor for a [`re_types::datatypes::Float32`] value from zero to max float with a suffix. +pub fn edit_f32_zero_to_max_with_suffix( _ctx: &re_viewer_context::ViewerContext<'_>, ui: &mut egui::Ui, value: &mut MaybeMutRef<'_, impl std::ops::DerefMut>, + suffix: &str, ) -> egui::Response { let mut value: MaybeMutRef<'_, f32> = match value { MaybeMutRef::Ref(value) => MaybeMutRef::Ref(value), MaybeMutRef::MutRef(value) => MaybeMutRef::MutRef(&mut value.deref_mut().0), }; - edit_f32_float_raw(ui, &mut value, 0.0..=f32::MAX) + edit_f32_float_raw(ui, &mut value, 0.0..=f32::MAX, suffix) +} + +/// Generic editor for a [`re_types::datatypes::Float32`] value representing a ui points value. +pub fn edit_ui_points( + ctx: &re_viewer_context::ViewerContext<'_>, + ui: &mut egui::Ui, + value: &mut MaybeMutRef<'_, impl std::ops::DerefMut>, +) -> egui::Response { + edit_f32_zero_to_max_with_suffix(ctx, ui, value, "pt") } /// Generic editor for a [`re_types::datatypes::Float32`] value from min to max float. @@ -27,7 +46,7 @@ pub fn edit_f32_min_to_max_float( MaybeMutRef::Ref(value) => MaybeMutRef::Ref(value), MaybeMutRef::MutRef(value) => MaybeMutRef::MutRef(&mut value.deref_mut().0), }; - edit_f32_float_raw(ui, &mut value, f32::MIN..=f32::MAX) + edit_f32_float_raw(ui, &mut value, f32::MIN..=f32::MAX, "") } /// Non monomorphized implementation for f32 float editing. @@ -35,9 +54,10 @@ pub fn edit_f32_float_raw( ui: &mut egui::Ui, value: &mut MaybeMutRef<'_, f32>, range: RangeInclusive, + suffix: &str, ) -> egui::Response { let speed = (value.abs() * 0.01).at_least(0.001); - edit_f32_float_raw_with_speed_impl(ui, value, range, speed) + edit_f32_float_raw_with_speed_impl(ui, value, range, speed, suffix) } /// Non monomorphized implementation for f32 float editing with a given speed. @@ -46,16 +66,18 @@ pub fn edit_f32_float_raw_with_speed_impl( value: &mut MaybeMutRef<'_, f32>, range: RangeInclusive, speed: f32, + suffix: &str, ) -> egui::Response { if let Some(value) = value.as_mut() { ui.add( egui::DragValue::new(value) .clamp_existing_to_range(false) .range(range) - .speed(speed), + .speed(speed) + .suffix(suffix), ) } else { - ui.label(re_format::format_f32(**value)) + ui.label(format!("{}{}", re_format::format_f32(**value), suffix)) } } diff --git a/crates/viewer/re_component_ui/src/datatype_uis/mod.rs b/crates/viewer/re_component_ui/src/datatype_uis/mod.rs index 33e6997985c8..9a8db3c714f9 100644 --- a/crates/viewer/re_component_ui/src/datatype_uis/mod.rs +++ b/crates/viewer/re_component_ui/src/datatype_uis/mod.rs @@ -14,7 +14,7 @@ pub use enum_combobox::{ }; pub use float_drag::{ edit_f32_float_raw, edit_f32_min_to_max_float, edit_f32_zero_to_max, edit_f32_zero_to_one, - edit_f64_float_raw_with_speed_impl, + edit_f64_float_raw_with_speed_impl, edit_ui_points, }; pub use range1d::edit_view_range1d; pub use singleline_string::{ diff --git a/crates/viewer/re_component_ui/src/datatype_uis/vec.rs b/crates/viewer/re_component_ui/src/datatype_uis/vec.rs index a0e7fe2eb4df..2c06dd16c505 100644 --- a/crates/viewer/re_component_ui/src/datatype_uis/vec.rs +++ b/crates/viewer/re_component_ui/src/datatype_uis/vec.rs @@ -36,7 +36,7 @@ fn edit_or_view_vector_component_immutable( MaybeMutRef::MutRef(value) => MaybeMutRef::Ref(&value[i]), }; - edit_f32_float_raw(ui, &mut value, f32::MIN..=f32::MAX) + edit_f32_float_raw(ui, &mut value, f32::MIN..=f32::MAX, "") } pub fn edit_or_view_vec3d_raw( @@ -57,5 +57,5 @@ fn edit_or_view_vector_component( MaybeMutRef::Ref(value) => MaybeMutRef::Ref(&value[i]), MaybeMutRef::MutRef(value) => MaybeMutRef::MutRef(&mut value[i]), }; - edit_f32_float_raw(ui, &mut value, f32::MIN..=f32::MAX) + edit_f32_float_raw(ui, &mut value, f32::MIN..=f32::MAX, "") } diff --git a/crates/viewer/re_component_ui/src/lib.rs b/crates/viewer/re_component_ui/src/lib.rs index df5bbb282040..55b7da2d4730 100644 --- a/crates/viewer/re_component_ui/src/lib.rs +++ b/crates/viewer/re_component_ui/src/lib.rs @@ -29,14 +29,13 @@ mod zoom_level; use datatype_uis::{ display_name_ui, display_text_ui, edit_bool, edit_f32_min_to_max_float, edit_f32_zero_to_max, edit_f32_zero_to_one, edit_multiline_string, edit_or_view_vec3d, edit_singleline_string, - edit_view_enum, edit_view_enum_with_variant_available, edit_view_range1d, view_uuid, - view_view_id, + edit_ui_points, edit_view_enum, edit_view_enum_with_variant_available, edit_view_range1d, + view_uuid, view_view_id, }; use re_types::{ blueprint::components::{ - BackgroundKind, Corner2D, GridSpacing, LockRangeDuringZoom, MapProvider, UiRadius, ViewFit, - Visible, + BackgroundKind, Corner2D, GridSpacing, LockRangeDuringZoom, MapProvider, ViewFit, Visible, }, components::{ AggregationPolicy, AlbedoFactor, AxisLength, Color, DepthMeter, DrawOrder, FillMode, @@ -75,9 +74,8 @@ pub fn create_component_ui_registry() -> re_viewer_context::ComponentUiRegistry registry.add_singleline_edit_or_view::(edit_f32_zero_to_max); registry.add_singleline_edit_or_view::(edit_f32_zero_to_max); registry.add_singleline_edit_or_view::(edit_f32_zero_to_max); - registry.add_singleline_edit_or_view::(edit_f32_zero_to_max); - registry.add_singleline_edit_or_view::(edit_f32_zero_to_max); - registry.add_singleline_edit_or_view::(edit_f32_zero_to_max); + registry.add_singleline_edit_or_view::(edit_ui_points); + registry.add_singleline_edit_or_view::(edit_ui_points); // float min-max components: registry.add_singleline_edit_or_view::(edit_f32_min_to_max_float); diff --git a/crates/viewer/re_component_ui/src/plane3d.rs b/crates/viewer/re_component_ui/src/plane3d.rs index d2870fdbc7a1..5bbd4323d0e3 100644 --- a/crates/viewer/re_component_ui/src/plane3d.rs +++ b/crates/viewer/re_component_ui/src/plane3d.rs @@ -114,7 +114,8 @@ pub fn edit_or_view_plane3d( MaybeMutRef::Ref(value) => MaybeMutRef::Ref(&value.0 .0[3]), MaybeMutRef::MutRef(value) => MaybeMutRef::MutRef(&mut value.0 .0[3]), }; - let distance_response = edit_f32_float_raw(ui, &mut maybe_mut_distance, f32::MIN..=f32::MAX); + let distance_response = + edit_f32_float_raw(ui, &mut maybe_mut_distance, f32::MIN..=f32::MAX, ""); normal_response | distance_response } @@ -150,7 +151,7 @@ pub fn multiline_edit_or_view_plane3d( }; any_edit |= - edit_f32_float_raw(ui, &mut maybe_mut_distance, f32::MIN..=f32::MAX).changed(); + edit_f32_float_raw(ui, &mut maybe_mut_distance, f32::MIN..=f32::MAX, "").changed(); }), ); diff --git a/crates/viewer/re_space_view_spatial/src/ui_3d.rs b/crates/viewer/re_space_view_spatial/src/ui_3d.rs index 294912118ed0..e5e5d5e104c9 100644 --- a/crates/viewer/re_space_view_spatial/src/ui_3d.rs +++ b/crates/viewer/re_space_view_spatial/src/ui_3d.rs @@ -15,7 +15,7 @@ use re_space_view::controls::{ use re_types::{ blueprint::{ archetypes::{Background, LineGrid3D}, - components::{GridSpacing, UiRadius, Visible}, + components::{GridSpacing, Visible}, }, components::ViewCoordinates, view_coordinates::SignedAxis3, @@ -722,8 +722,8 @@ impl SpatialSpaceView3D { } let spacing = **grid_config.component_or_fallback::(ctx, self, state)?; - let thickness_ui = - (**grid_config.component_or_fallback::(ctx, self, state)?) * 2.0; + let thickness_ui = **grid_config + .component_or_fallback::(ctx, self, state)?; let color = grid_config.component_or_fallback::(ctx, self, state)?; let plane = diff --git a/crates/viewer/re_space_view_spatial/src/view_3d_properties.rs b/crates/viewer/re_space_view_spatial/src/view_3d_properties.rs index 304083171007..851c5aea267c 100644 --- a/crates/viewer/re_space_view_spatial/src/view_3d_properties.rs +++ b/crates/viewer/re_space_view_spatial/src/view_3d_properties.rs @@ -1,9 +1,9 @@ use re_types::{ blueprint::{ archetypes::{Background, LineGrid3D}, - components::{BackgroundKind, UiRadius}, + components::BackgroundKind, }, - components::{Color, Plane3D}, + components::{Color, Plane3D, StrokeWidth}, Archetype, }; use re_viewer_context::{SpaceViewStateExt as _, TypedComponentFallbackProvider}; @@ -29,14 +29,9 @@ impl TypedComponentFallbackProvider for SpatialSpaceView3D { } } -impl TypedComponentFallbackProvider for SpatialSpaceView3D { - fn fallback_for(&self, ctx: &re_viewer_context::QueryContext<'_>) -> UiRadius { - if ctx.archetype_name == Some(LineGrid3D::name()) { - // 1 ui unit thickness by default. - 0.5.into() - } else { - 1.0.into() - } +impl TypedComponentFallbackProvider for SpatialSpaceView3D { + fn fallback_for(&self, _ctx: &re_viewer_context::QueryContext<'_>) -> StrokeWidth { + 1.0.into() } } @@ -56,4 +51,4 @@ impl TypedComponentFallbackProvider for SpatialSpaceView3D { } } -re_viewer_context::impl_component_fallback_provider!(SpatialSpaceView3D => [BackgroundKind, Color, UiRadius, Plane3D]); +re_viewer_context::impl_component_fallback_provider!(SpatialSpaceView3D => [BackgroundKind, Color, StrokeWidth, Plane3D]); diff --git a/crates/viewer/re_viewer/src/blueprint/validation_gen/mod.rs b/crates/viewer/re_viewer/src/blueprint/validation_gen/mod.rs index 7d045fbfe00d..85bc964e87a8 100644 --- a/crates/viewer/re_viewer/src/blueprint/validation_gen/mod.rs +++ b/crates/viewer/re_viewer/src/blueprint/validation_gen/mod.rs @@ -22,7 +22,6 @@ pub use re_types::blueprint::components::SpaceViewClass; pub use re_types::blueprint::components::SpaceViewOrigin; pub use re_types::blueprint::components::TensorDimensionIndexSlider; pub use re_types::blueprint::components::TimelineName; -pub use re_types::blueprint::components::UiRadius; pub use re_types::blueprint::components::ViewFit; pub use re_types::blueprint::components::ViewerRecommendationHash; pub use re_types::blueprint::components::Visible; @@ -68,7 +67,6 @@ pub fn is_valid_blueprint(blueprint: &EntityDb) -> bool { && validate_component::(blueprint) && validate_component::(blueprint) && validate_component::(blueprint) - && validate_component::(blueprint) && validate_component::(blueprint) && validate_component::(blueprint) && validate_component::(blueprint) diff --git a/crates/viewer/re_viewer/src/reflection/mod.rs b/crates/viewer/re_viewer/src/reflection/mod.rs index 8c4e731e91fc..5705b3f3622e 100644 --- a/crates/viewer/re_viewer/src/reflection/mod.rs +++ b/crates/viewer/re_viewer/src/reflection/mod.rs @@ -254,14 +254,6 @@ fn generate_component_reflection() -> Result::name(), - ComponentReflection { - docstring_md: "Like `Radius`, but in always in ui units.", - custom_placeholder: None, - datatype: UiRadius::arrow2_datatype(), - }, - ), ( ::name(), ComponentReflection { @@ -1973,9 +1965,9 @@ fn generate_archetype_reflection() -> ArchetypeReflectionMap { docstring_md : "In what plane the grid is drawn.\n\nDefaults to whatever plane is determined as the plane at zero units up/down as defined by [`archetype.ViewCoordinates`] if present.", is_required : false, }, ArchetypeFieldReflection { component_name : - "rerun.blueprint.components.UiRadius".into(), display_name : - "Line radius", docstring_md : - "How thick the lines should be in ui units.\n\nDefault is 0.5 ui unit.", + "rerun.components.StrokeWidth".into(), display_name : "Stroke width", + docstring_md : + "How thick the lines should be in ui units.\n\nDefault is 1.0 ui unit.", is_required : false, }, ArchetypeFieldReflection { component_name : "rerun.components.Color".into(), display_name : "Color", docstring_md : diff --git a/docs/content/reference/types/views/spatial3d_view.md b/docs/content/reference/types/views/spatial3d_view.md index d375741e0644..a6efe92e9ac1 100644 --- a/docs/content/reference/types/views/spatial3d_view.md +++ b/docs/content/reference/types/views/spatial3d_view.md @@ -18,7 +18,7 @@ Configuration for the 3D line grid. * `visible`: Whether the grid is visible. * `spacing`: Space between grid lines spacing of one line to the next in scene units. * `plane`: In what plane the grid is drawn. -* `line_radius`: How thick the lines should be in ui units. +* `stroke_width`: How thick the lines should be in ui units. * `color`: Color used for the grid. ### `time_ranges` Configures which range on each timeline is shown by this view (unless specified differently per entity). diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.cpp b/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.cpp index 7d88029b2092..d1524ed49629 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.cpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.cpp @@ -31,8 +31,8 @@ namespace rerun { RR_RETURN_NOT_OK(result.error); cells.push_back(std::move(result.value)); } - if (archetype.line_radius.has_value()) { - auto result = ComponentBatch::from_loggable(archetype.line_radius.value()); + if (archetype.stroke_width.has_value()) { + auto result = ComponentBatch::from_loggable(archetype.stroke_width.value()); RR_RETURN_NOT_OK(result.error); cells.push_back(std::move(result.value)); } diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.hpp b/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.hpp index 89bb801d47ac..14df2133ee4f 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.hpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.hpp @@ -4,13 +4,13 @@ #pragma once #include "../../blueprint/components/grid_spacing.hpp" -#include "../../blueprint/components/ui_radius.hpp" #include "../../blueprint/components/visible.hpp" #include "../../collection.hpp" #include "../../compiler_utils.hpp" #include "../../component_batch.hpp" #include "../../components/color.hpp" #include "../../components/plane3d.hpp" +#include "../../components/stroke_width.hpp" #include "../../indicator_component.hpp" #include "../../result.hpp" @@ -37,8 +37,8 @@ namespace rerun::blueprint::archetypes { /// How thick the lines should be in ui units. /// - /// Default is 0.5 ui unit. - std::optional line_radius; + /// Default is 1.0 ui unit. + std::optional stroke_width; /// Color used for the grid. /// @@ -84,9 +84,9 @@ namespace rerun::blueprint::archetypes { /// How thick the lines should be in ui units. /// - /// Default is 0.5 ui unit. - LineGrid3D with_line_radius(rerun::blueprint::components::UiRadius _line_radius) && { - line_radius = std::move(_line_radius); + /// Default is 1.0 ui unit. + LineGrid3D with_stroke_width(rerun::components::StrokeWidth _stroke_width) && { + stroke_width = std::move(_stroke_width); // See: https://github.com/rerun-io/rerun/issues/4027 RR_WITH_MAYBE_UNINITIALIZED_DISABLED(return std::move(*this);) } diff --git a/rerun_cpp/src/rerun/blueprint/components.hpp b/rerun_cpp/src/rerun/blueprint/components.hpp index 3cbea75f71f0..6dfe128cab3c 100644 --- a/rerun_cpp/src/rerun/blueprint/components.hpp +++ b/rerun_cpp/src/rerun/blueprint/components.hpp @@ -29,7 +29,6 @@ #include "blueprint/components/space_view_origin.hpp" #include "blueprint/components/tensor_dimension_index_slider.hpp" #include "blueprint/components/timeline_name.hpp" -#include "blueprint/components/ui_radius.hpp" #include "blueprint/components/view_fit.hpp" #include "blueprint/components/viewer_recommendation_hash.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 f1f37065f76c..50a1a60a3463 100644 --- a/rerun_cpp/src/rerun/blueprint/components/.gitattributes +++ b/rerun_cpp/src/rerun/blueprint/components/.gitattributes @@ -33,7 +33,6 @@ space_view_maximized.hpp linguist-generated=true space_view_origin.hpp linguist-generated=true tensor_dimension_index_slider.hpp linguist-generated=true timeline_name.hpp linguist-generated=true -ui_radius.hpp linguist-generated=true view_fit.cpp linguist-generated=true view_fit.hpp linguist-generated=true viewer_recommendation_hash.hpp linguist-generated=true diff --git a/rerun_cpp/src/rerun/blueprint/components/ui_radius.hpp b/rerun_cpp/src/rerun/blueprint/components/ui_radius.hpp deleted file mode 100644 index 5141e3f871f8..000000000000 --- a/rerun_cpp/src/rerun/blueprint/components/ui_radius.hpp +++ /dev/null @@ -1,74 +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/blueprint/components/ui_radius.fbs". - -#pragma once - -#include "../../datatypes/float32.hpp" -#include "../../result.hpp" - -#include -#include - -namespace rerun::blueprint::components { - /// **Component**: Like `Radius`, but in always in ui units. - struct UiRadius { - /// Radius in ui units. - rerun::datatypes::Float32 radius; - - public: - UiRadius() = default; - - UiRadius(rerun::datatypes::Float32 radius_) : radius(radius_) {} - - UiRadius& operator=(rerun::datatypes::Float32 radius_) { - radius = radius_; - return *this; - } - - UiRadius(float value_) : radius(value_) {} - - UiRadius& operator=(float value_) { - radius = value_; - return *this; - } - - /// Cast to the underlying Float32 datatype - operator rerun::datatypes::Float32() const { - return radius; - } - }; -} // namespace rerun::blueprint::components - -namespace rerun { - static_assert(sizeof(rerun::datatypes::Float32) == sizeof(blueprint::components::UiRadius)); - - /// \private - template <> - struct Loggable { - static constexpr const char Name[] = "rerun.blueprint.components.UiRadius"; - - /// Returns the arrow data type this type corresponds to. - static const std::shared_ptr& arrow_datatype() { - return Loggable::arrow_datatype(); - } - - /// Serializes an array of `rerun::blueprint:: components::UiRadius` into an arrow array. - static Result> to_arrow( - const blueprint::components::UiRadius* instances, size_t num_instances - ) { - if (num_instances == 0) { - return Loggable::to_arrow(nullptr, 0); - } else if (instances == nullptr) { - return rerun::Error( - ErrorCode::UnexpectedNullArgument, - "Passed array instances is null when num_elements> 0." - ); - } else { - return Loggable::to_arrow( - &instances->radius, - num_instances - ); - } - } - }; -} // namespace rerun diff --git a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/line_grid3d.py b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/line_grid3d.py index bec846001ae5..2422169539ce 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/line_grid3d.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/line_grid3d.py @@ -29,7 +29,7 @@ def __init__( visible: datatypes.BoolLike | None = None, spacing: datatypes.Float32Like | None = None, plane: datatypes.Plane3DLike | None = None, - line_radius: datatypes.Float32Like | None = None, + stroke_width: datatypes.Float32Like | None = None, color: datatypes.Rgba32Like | None = None, ): """ @@ -47,10 +47,10 @@ def __init__( In what plane the grid is drawn. Defaults to whatever plane is determined as the plane at zero units up/down as defined by [`archetype.ViewCoordinates`] if present. - line_radius: + stroke_width: How thick the lines should be in ui units. - Default is 0.5 ui unit. + Default is 1.0 ui unit. color: Color used for the grid. @@ -61,7 +61,7 @@ def __init__( # You can define your own __init__ function as a member of LineGrid3DExt in line_grid3d_ext.py with catch_and_log_exceptions(context=self.__class__.__name__): - self.__attrs_init__(visible=visible, spacing=spacing, plane=plane, line_radius=line_radius, color=color) + self.__attrs_init__(visible=visible, spacing=spacing, plane=plane, stroke_width=stroke_width, color=color) return self.__attrs_clear__() @@ -71,7 +71,7 @@ def __attrs_clear__(self) -> None: visible=None, # type: ignore[arg-type] spacing=None, # type: ignore[arg-type] plane=None, # type: ignore[arg-type] - line_radius=None, # type: ignore[arg-type] + stroke_width=None, # type: ignore[arg-type] color=None, # type: ignore[arg-type] ) @@ -113,14 +113,14 @@ def _clear(cls) -> LineGrid3D: # # (Docstring intentionally commented out to hide this field from the docs) - line_radius: blueprint_components.UiRadiusBatch | None = field( + stroke_width: components.StrokeWidthBatch | None = field( metadata={"component": "optional"}, default=None, - converter=blueprint_components.UiRadiusBatch._optional, # type: ignore[misc] + converter=components.StrokeWidthBatch._optional, # type: ignore[misc] ) # How thick the lines should be in ui units. # - # Default is 0.5 ui unit. + # Default is 1.0 ui unit. # # (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 d613772faf83..320328225835 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/components/.gitattributes +++ b/rerun_py/rerun_sdk/rerun/blueprint/components/.gitattributes @@ -29,7 +29,6 @@ space_view_maximized.py linguist-generated=true space_view_origin.py linguist-generated=true tensor_dimension_index_slider.py linguist-generated=true timeline_name.py linguist-generated=true -ui_radius.py linguist-generated=true view_fit.py linguist-generated=true viewer_recommendation_hash.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 ef4d270cad7a..8f7f6182b390 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/components/__init__.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/components/__init__.py @@ -29,7 +29,6 @@ from .space_view_origin import SpaceViewOrigin, SpaceViewOriginBatch from .tensor_dimension_index_slider import TensorDimensionIndexSlider, TensorDimensionIndexSliderBatch from .timeline_name import TimelineName, TimelineNameBatch -from .ui_radius import UiRadius, UiRadiusBatch from .view_fit import ViewFit, ViewFitArrayLike, ViewFitBatch, ViewFitLike from .viewer_recommendation_hash import ViewerRecommendationHash, ViewerRecommendationHashBatch from .visible import Visible, VisibleBatch @@ -103,8 +102,6 @@ "TensorDimensionIndexSliderBatch", "TimelineName", "TimelineNameBatch", - "UiRadius", - "UiRadiusBatch", "ViewFit", "ViewFitArrayLike", "ViewFitBatch", diff --git a/rerun_py/rerun_sdk/rerun/blueprint/components/ui_radius.py b/rerun_py/rerun_sdk/rerun/blueprint/components/ui_radius.py deleted file mode 100644 index 322572fe21f5..000000000000 --- a/rerun_py/rerun_sdk/rerun/blueprint/components/ui_radius.py +++ /dev/null @@ -1,32 +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/blueprint/components/ui_radius.fbs". - -# You can extend this class by creating a "UiRadiusExt" class in "ui_radius_ext.py". - -from __future__ import annotations - -from ... import datatypes -from ..._baseclasses import ( - ComponentBatchMixin, - ComponentMixin, -) - -__all__ = ["UiRadius", "UiRadiusBatch"] - - -class UiRadius(datatypes.Float32, ComponentMixin): - """**Component**: Like `Radius`, but in always in ui units.""" - - _BATCH_TYPE = None - # You can define your own __init__ function as a member of UiRadiusExt in ui_radius_ext.py - - # Note: there are no fields here because UiRadius delegates to datatypes.Float32 - pass - - -class UiRadiusBatch(datatypes.Float32Batch, ComponentBatchMixin): - _COMPONENT_NAME: str = "rerun.blueprint.components.UiRadius" - - -# This is patched in late to avoid circular dependencies. -UiRadius._BATCH_TYPE = UiRadiusBatch # type: ignore[assignment] From 9dae90570425223ea628fc644bbccb37414cfb44 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Tue, 3 Dec 2024 18:18:20 +0100 Subject: [PATCH 19/29] make grid more transparent --- crates/viewer/re_space_view_spatial/src/view_3d_properties.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/viewer/re_space_view_spatial/src/view_3d_properties.rs b/crates/viewer/re_space_view_spatial/src/view_3d_properties.rs index 851c5aea267c..60721a944df4 100644 --- a/crates/viewer/re_space_view_spatial/src/view_3d_properties.rs +++ b/crates/viewer/re_space_view_spatial/src/view_3d_properties.rs @@ -16,7 +16,7 @@ impl TypedComponentFallbackProvider for SpatialSpaceView3D { if ctx.archetype_name == Some(Background::name()) { Color::WHITE } else if ctx.archetype_name == Some(LineGrid3D::name()) { - Color::from_unmultiplied_rgba(128, 128, 128, 128) + Color::from_unmultiplied_rgba(128, 128, 128, 60) } else { Color::default() } From 06b55da152f36dcf951616ee8090ae4ac30ee651 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Tue, 3 Dec 2024 18:53:58 +0100 Subject: [PATCH 20/29] make the world grid shader actually use the plane equation we're using in the docs --- crates/viewer/re_renderer/shader/utils/plane.wgsl | 7 ++++++- crates/viewer/re_renderer/shader/world_grid.wgsl | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/crates/viewer/re_renderer/shader/utils/plane.wgsl b/crates/viewer/re_renderer/shader/utils/plane.wgsl index ead2e2ec9945..6bf9d6cf01cb 100644 --- a/crates/viewer/re_renderer/shader/utils/plane.wgsl +++ b/crates/viewer/re_renderer/shader/utils/plane.wgsl @@ -1,3 +1,8 @@ +// A plane defined by `dot(normal, X) - distance = 0`. +// +// This is known as Hesse normal form. +// Note that we're subtracting distance, in some literature this term is added instead. +// This form is more usually more convenient as it expresses "above the plane" as `dot(normal, X) > distance`. struct Plane { normal: vec3f, distance: f32, @@ -5,5 +10,5 @@ struct Plane { /// How far away is a given point from the plane? fn distance_to_plane(plane: Plane, point: vec3f) -> f32 { - return dot(plane.normal, point) + plane.distance; + return dot(plane.normal, point) - plane.distance; } diff --git a/crates/viewer/re_renderer/shader/world_grid.wgsl b/crates/viewer/re_renderer/shader/world_grid.wgsl index a6b0c144817e..0f78a2699964 100644 --- a/crates/viewer/re_renderer/shader/world_grid.wgsl +++ b/crates/viewer/re_renderer/shader/world_grid.wgsl @@ -57,7 +57,7 @@ fn main_vs(@builtin(vertex_index) v_idx: u32) -> VertexOutput { let shifted_plane_position = plane_position + camera_on_plane; // Compute world position from shifted plane position. - let world_position = config.plane.normal * -config.plane.distance + plane_x_axis * shifted_plane_position.x + plane_y_axis * shifted_plane_position.y; + let world_position = config.plane.normal * config.plane.distance + plane_x_axis * shifted_plane_position.x + plane_y_axis * shifted_plane_position.y; out.position = frame.projection_from_world * vec4f(world_position, 1.0); // Determine which "scales" of the grid we want to show. We want to show factor 1, 10, 100, 1000, etc. From e464ba4a0a61cb07ac379080f7033fe5ca9aabbc Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Tue, 3 Dec 2024 19:10:48 +0100 Subject: [PATCH 21/29] extend spatial view example, implement python extensions, fix doc links --- .../rerun/archetypes/instance_poses3d.fbs | 2 +- .../definitions/rerun/archetypes/pinhole.fbs | 2 +- .../blueprint/archetypes/line_grid_3d.fbs | 5 +- .../definitions/rerun/components/plane3d.fbs | 3 +- .../definitions/rerun/datatypes/plane3d.fbs | 3 +- .../src/archetypes/instance_poses3d.rs | 2 +- .../store/re_types/src/archetypes/pinhole.rs | 4 +- .../src/blueprint/archetypes/line_grid3d.rs | 10 +++- .../store/re_types/src/components/plane3d.rs | 3 +- .../re_types/src/components/plane3d_ext.rs | 4 +- .../store/re_types/src/datatypes/plane3d.rs | 3 +- .../re_types/src/datatypes/plane3d_ext.rs | 4 +- crates/viewer/re_viewer/src/reflection/mod.rs | 8 +-- .../types/archetypes/instance_poses3d.md | 2 +- .../reference/types/components/plane3d.md | 3 +- .../reference/types/datatypes/plane3d.md | 3 +- docs/snippets/all/views/spatial3d.py | 9 +++ .../src/rerun/archetypes/instance_poses3d.hpp | 2 +- rerun_cpp/src/rerun/archetypes/pinhole.hpp | 4 +- .../blueprint/archetypes/line_grid3d.hpp | 10 +++- rerun_cpp/src/rerun/components/plane3d.hpp | 3 +- rerun_cpp/src/rerun/datatypes/plane3d.hpp | 3 +- .../rerun/archetypes/instance_poses3d.py | 2 +- .../rerun_sdk/rerun/archetypes/pinhole.py | 2 +- .../rerun/blueprint/archetypes/line_grid3d.py | 10 +++- .../rerun/blueprint/views/spatial3d_view.py | 9 +++ .../rerun_sdk/rerun/components/plane3d.py | 3 +- rerun_py/rerun_sdk/rerun/datatypes/plane3d.py | 19 +++--- .../rerun_sdk/rerun/datatypes/plane3d_ext.py | 59 +++++++++++++++++++ 29 files changed, 151 insertions(+), 45 deletions(-) create mode 100644 rerun_py/rerun_sdk/rerun/datatypes/plane3d_ext.py diff --git a/crates/store/re_types/definitions/rerun/archetypes/instance_poses3d.fbs b/crates/store/re_types/definitions/rerun/archetypes/instance_poses3d.fbs index 4e753cc21e21..4578e5668f85 100644 --- a/crates/store/re_types/definitions/rerun/archetypes/instance_poses3d.fbs +++ b/crates/store/re_types/definitions/rerun/archetypes/instance_poses3d.fbs @@ -13,7 +13,7 @@ namespace rerun.archetypes; /// /// Currently, many visualizers support only a single instance transform per entity. /// Check archetype documentations for details - if not otherwise specified, only the first instance transform is applied. -/// Some visualizers like the mesh visualizer used for [`archetype.Mesh3D`], +/// Some visualizers like the mesh visualizer used for [archetype.Mesh3D], /// will draw an object for every pose, a behavior also known as "instancing". /// /// \example archetypes/instance_poses3d_combined title="Regular & instance transforms in tandem" image="https://static.rerun.io/leaf_transform3d/41674f0082d6de489f8a1cd1583f60f6b5820ddf/1200w.png" diff --git a/crates/store/re_types/definitions/rerun/archetypes/pinhole.fbs b/crates/store/re_types/definitions/rerun/archetypes/pinhole.fbs index 65ad644ef7bc..e5071aacb00f 100644 --- a/crates/store/re_types/definitions/rerun/archetypes/pinhole.fbs +++ b/crates/store/re_types/definitions/rerun/archetypes/pinhole.fbs @@ -32,7 +32,7 @@ table Pinhole ( /// Sets the view coordinates for the camera. /// - /// All common values are available as constants on the `components.ViewCoordinates` class. + /// All common values are available as constants on the [components.ViewCoordinates] class. /// /// The default is `ViewCoordinates::RDF`, i.e. X=Right, Y=Down, Z=Forward, and this is also the recommended setting. /// This means that the camera frustum will point along the positive Z axis of the parent space, diff --git a/crates/store/re_types/definitions/rerun/blueprint/archetypes/line_grid_3d.fbs b/crates/store/re_types/definitions/rerun/blueprint/archetypes/line_grid_3d.fbs index 11e6ac802380..3143471766f1 100644 --- a/crates/store/re_types/definitions/rerun/blueprint/archetypes/line_grid_3d.fbs +++ b/crates/store/re_types/definitions/rerun/blueprint/archetypes/line_grid_3d.fbs @@ -10,11 +10,14 @@ table LineGrid3D ( visible: rerun.blueprint.components.Visible ("attr.rerun.component_optional", nullable, order: 1000); /// Space between grid lines spacing of one line to the next in scene units. + /// + /// As you zoom out, successively only every tenth line is shown. + /// This controls the closest zoom level. spacing: rerun.blueprint.components.GridSpacing ("attr.rerun.component_optional", nullable, order: 2000); /// In what plane the grid is drawn. /// - /// Defaults to whatever plane is determined as the plane at zero units up/down as defined by [`archetype.ViewCoordinates`] if present. + /// Defaults to whatever plane is determined as the plane at zero units up/down as defined by [components.ViewCoordinates] if present. plane: rerun.components.Plane3D ("attr.rerun.component_optional", nullable, order: 3000); /// How thick the lines should be in ui units. diff --git a/crates/store/re_types/definitions/rerun/components/plane3d.fbs b/crates/store/re_types/definitions/rerun/components/plane3d.fbs index 9ec3fd3d147c..e60aa4efdf58 100644 --- a/crates/store/re_types/definitions/rerun/components/plane3d.fbs +++ b/crates/store/re_types/definitions/rerun/components/plane3d.fbs @@ -2,7 +2,8 @@ namespace rerun.components; /// An infinite 3D plane represented by a unit normal vector and a distance. /// -/// Any point P on the plane fulfills the equation `dot(xyz, P) - d = 0`, where `xyz` is the plane's normal and `d` the distance. +/// Any point P on the plane fulfills the equation `dot(xyz, P) - d = 0`, +/// where `xyz` is the plane's normal and `d` the distance of the plane from the origin. /// This representation is also known as the Hesse normal form. /// /// Note: although the normal will be passed through to the diff --git a/crates/store/re_types/definitions/rerun/datatypes/plane3d.fbs b/crates/store/re_types/definitions/rerun/datatypes/plane3d.fbs index 2d02dbfe1515..a490f8450481 100644 --- a/crates/store/re_types/definitions/rerun/datatypes/plane3d.fbs +++ b/crates/store/re_types/definitions/rerun/datatypes/plane3d.fbs @@ -2,7 +2,8 @@ namespace rerun.datatypes; /// An infinite 3D plane represented by a unit normal vector and a distance. /// -/// Any point P on the plane fulfills the equation `dot(xyz, P) - d = 0`, where `xyz` is the plane's normal and `d` the distance. +/// Any point P on the plane fulfills the equation `dot(xyz, P) - d = 0`, +/// where `xyz` is the plane's normal and `d` the distance of the plane from the origin. /// This representation is also known as the Hesse normal form. /// /// Note: although the normal will be passed through to the diff --git a/crates/store/re_types/src/archetypes/instance_poses3d.rs b/crates/store/re_types/src/archetypes/instance_poses3d.rs index 0903a53dfb68..530eb5da6f1f 100644 --- a/crates/store/re_types/src/archetypes/instance_poses3d.rs +++ b/crates/store/re_types/src/archetypes/instance_poses3d.rs @@ -30,7 +30,7 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; /// /// Currently, many visualizers support only a single instance transform per entity. /// Check archetype documentations for details - if not otherwise specified, only the first instance transform is applied. -/// Some visualizers like the mesh visualizer used for [`archetype.Mesh3D`], +/// Some visualizers like the mesh visualizer used for [`archetype::Mesh3D`][crate::archetype::Mesh3D], /// will draw an object for every pose, a behavior also known as "instancing". /// /// ## Example diff --git a/crates/store/re_types/src/archetypes/pinhole.rs b/crates/store/re_types/src/archetypes/pinhole.rs index 95d09610101d..1ccdbb8fa87b 100644 --- a/crates/store/re_types/src/archetypes/pinhole.rs +++ b/crates/store/re_types/src/archetypes/pinhole.rs @@ -103,7 +103,7 @@ pub struct Pinhole { /// Sets the view coordinates for the camera. /// - /// All common values are available as constants on the `components.ViewCoordinates` class. + /// All common values are available as constants on the [`components::ViewCoordinates`][crate::components::ViewCoordinates] class. /// /// The default is `ViewCoordinates::RDF`, i.e. X=Right, Y=Down, Z=Forward, and this is also the recommended setting. /// This means that the camera frustum will point along the positive Z axis of the parent space, @@ -345,7 +345,7 @@ impl Pinhole { /// Sets the view coordinates for the camera. /// - /// All common values are available as constants on the `components.ViewCoordinates` class. + /// All common values are available as constants on the [`components::ViewCoordinates`][crate::components::ViewCoordinates] class. /// /// The default is `ViewCoordinates::RDF`, i.e. X=Right, Y=Down, Z=Forward, and this is also the recommended setting. /// This means that the camera frustum will point along the positive Z axis of the parent space, diff --git a/crates/store/re_types/src/blueprint/archetypes/line_grid3d.rs b/crates/store/re_types/src/blueprint/archetypes/line_grid3d.rs index 755bc4a5b995..b594d2176086 100644 --- a/crates/store/re_types/src/blueprint/archetypes/line_grid3d.rs +++ b/crates/store/re_types/src/blueprint/archetypes/line_grid3d.rs @@ -27,11 +27,14 @@ pub struct LineGrid3D { pub visible: Option, /// Space between grid lines spacing of one line to the next in scene units. + /// + /// As you zoom out, successively only every tenth line is shown. + /// This controls the closest zoom level. pub spacing: Option, /// In what plane the grid is drawn. /// - /// Defaults to whatever plane is determined as the plane at zero units up/down as defined by [`archetype.ViewCoordinates`] if present. + /// Defaults to whatever plane is determined as the plane at zero units up/down as defined by [`components::ViewCoordinates`][crate::components::ViewCoordinates] if present. pub plane: Option, /// How thick the lines should be in ui units. @@ -265,6 +268,9 @@ impl LineGrid3D { } /// Space between grid lines spacing of one line to the next in scene units. + /// + /// As you zoom out, successively only every tenth line is shown. + /// This controls the closest zoom level. #[inline] pub fn with_spacing( mut self, @@ -276,7 +282,7 @@ impl LineGrid3D { /// In what plane the grid is drawn. /// - /// Defaults to whatever plane is determined as the plane at zero units up/down as defined by [`archetype.ViewCoordinates`] if present. + /// Defaults to whatever plane is determined as the plane at zero units up/down as defined by [`components::ViewCoordinates`][crate::components::ViewCoordinates] if present. #[inline] pub fn with_plane(mut self, plane: impl Into) -> Self { self.plane = Some(plane.into()); diff --git a/crates/store/re_types/src/components/plane3d.rs b/crates/store/re_types/src/components/plane3d.rs index da74eca48e94..d0addd824006 100644 --- a/crates/store/re_types/src/components/plane3d.rs +++ b/crates/store/re_types/src/components/plane3d.rs @@ -20,7 +20,8 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; /// **Component**: An infinite 3D plane represented by a unit normal vector and a distance. /// -/// Any point P on the plane fulfills the equation `dot(xyz, P) - d = 0`, where `xyz` is the plane's normal and `d` the distance. +/// Any point P on the plane fulfills the equation `dot(xyz, P) - d = 0`, +/// where `xyz` is the plane's normal and `d` the distance of the plane from the origin. /// This representation is also known as the Hesse normal form. /// /// Note: although the normal will be passed through to the diff --git a/crates/store/re_types/src/components/plane3d_ext.rs b/crates/store/re_types/src/components/plane3d_ext.rs index 5696bb1cf673..f8abe92faf26 100644 --- a/crates/store/re_types/src/components/plane3d_ext.rs +++ b/crates/store/re_types/src/components/plane3d_ext.rs @@ -14,8 +14,8 @@ impl Plane3D { /// /// The plane will not be normalized upon creation. #[inline] - pub fn new(normal: impl Into, d: f32) -> Self { - Self(crate::datatypes::Plane3D::new(normal, d)) + pub fn new(normal: impl Into, distance: f32) -> Self { + Self(crate::datatypes::Plane3D::new(normal, distance)) } } diff --git a/crates/store/re_types/src/datatypes/plane3d.rs b/crates/store/re_types/src/datatypes/plane3d.rs index e12fd4a2c1e5..54e8303158c1 100644 --- a/crates/store/re_types/src/datatypes/plane3d.rs +++ b/crates/store/re_types/src/datatypes/plane3d.rs @@ -20,7 +20,8 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; /// **Datatype**: An infinite 3D plane represented by a unit normal vector and a distance. /// -/// Any point P on the plane fulfills the equation `dot(xyz, P) - d = 0`, where `xyz` is the plane's normal and `d` the distance. +/// Any point P on the plane fulfills the equation `dot(xyz, P) - d = 0`, +/// where `xyz` is the plane's normal and `d` the distance of the plane from the origin. /// This representation is also known as the Hesse normal form. /// /// Note: although the normal will be passed through to the diff --git a/crates/store/re_types/src/datatypes/plane3d_ext.rs b/crates/store/re_types/src/datatypes/plane3d_ext.rs index b71e5b3d4b5b..3bcd454f45f5 100644 --- a/crates/store/re_types/src/datatypes/plane3d_ext.rs +++ b/crates/store/re_types/src/datatypes/plane3d_ext.rs @@ -26,9 +26,9 @@ impl Plane3D { /// /// The plane will not be normalized upon creation. #[inline] - pub fn new(normal: impl Into, d: f32) -> Self { + pub fn new(normal: impl Into, distance: f32) -> Self { let normal = normal.into(); - Self([normal.0[0], normal.0[1], normal.0[2], d]) + Self([normal.0[0], normal.0[1], normal.0[2], distance]) } } diff --git a/crates/viewer/re_viewer/src/reflection/mod.rs b/crates/viewer/re_viewer/src/reflection/mod.rs index 5705b3f3622e..ed5806fd9f5b 100644 --- a/crates/viewer/re_viewer/src/reflection/mod.rs +++ b/crates/viewer/re_viewer/src/reflection/mod.rs @@ -611,7 +611,7 @@ fn generate_component_reflection() -> Result::name(), ComponentReflection { - docstring_md: "An infinite 3D plane represented by a unit normal vector and a distance.\n\nAny point P on the plane fulfills the equation `dot(xyz, P) - d = 0`, where `xyz` is the plane's normal and `d` the distance.\nThis representation is also known as the Hesse normal form.\n\nNote: although the normal will be passed through to the\ndatastore as provided, when used in the Viewer, planes will always be normalized.\nI.e. the plane with xyz = (2, 0, 0), d = 1 is equivalent to xyz = (1, 0, 0), d = 0.5", + docstring_md: "An infinite 3D plane represented by a unit normal vector and a distance.\n\nAny point P on the plane fulfills the equation `dot(xyz, P) - d = 0`,\nwhere `xyz` is the plane's normal and `d` the distance of the plane from the origin.\nThis representation is also known as the Hesse normal form.\n\nNote: although the normal will be passed through to the\ndatastore as provided, when used in the Viewer, planes will always be normalized.\nI.e. the plane with xyz = (2, 0, 0), d = 1 is equivalent to xyz = (1, 0, 0), d = 0.5", custom_placeholder: None, datatype: Plane3D::arrow2_datatype(), }, @@ -1575,7 +1575,7 @@ fn generate_archetype_reflection() -> ArchetypeReflectionMap { is_required : false, }, ArchetypeFieldReflection { component_name : "rerun.components.ViewCoordinates".into(), display_name : "Camera xyz", docstring_md : - "Sets the view coordinates for the camera.\n\nAll common values are available as constants on the `components.ViewCoordinates` class.\n\nThe default is `ViewCoordinates::RDF`, i.e. X=Right, Y=Down, Z=Forward, and this is also the recommended setting.\nThis means that the camera frustum will point along the positive Z axis of the parent space,\nand the cameras \"up\" direction will be along the negative Y axis of the parent space.\n\nThe camera frustum will point whichever axis is set to `F` (or the opposite of `B`).\nWhen logging a depth image under this entity, this is the direction the point cloud will be projected.\nWith `RDF`, the default forward is +Z.\n\nThe frustum's \"up\" direction will be whichever axis is set to `U` (or the opposite of `D`).\nThis will match the negative Y direction of pixel space (all images are assumed to have xyz=RDF).\nWith `RDF`, the default is up is -Y.\n\nThe frustum's \"right\" direction will be whichever axis is set to `R` (or the opposite of `L`).\nThis will match the positive X direction of pixel space (all images are assumed to have xyz=RDF).\nWith `RDF`, the default right is +x.\n\nOther common formats are `RUB` (X=Right, Y=Up, Z=Back) and `FLU` (X=Forward, Y=Left, Z=Up).\n\nNOTE: setting this to something else than `RDF` (the default) will change the orientation of the camera frustum,\nand make the pinhole matrix not match up with the coordinate system of the pinhole entity.\n\nThe pinhole matrix (the `image_from_camera` argument) always project along the third (Z) axis,\nbut will be re-oriented to project along the forward axis of the `camera_xyz` argument.", + "Sets the view coordinates for the camera.\n\nAll common values are available as constants on the [`components.ViewCoordinates`](https://rerun.io/docs/reference/types/components/view_coordinates) class.\n\nThe default is `ViewCoordinates::RDF`, i.e. X=Right, Y=Down, Z=Forward, and this is also the recommended setting.\nThis means that the camera frustum will point along the positive Z axis of the parent space,\nand the cameras \"up\" direction will be along the negative Y axis of the parent space.\n\nThe camera frustum will point whichever axis is set to `F` (or the opposite of `B`).\nWhen logging a depth image under this entity, this is the direction the point cloud will be projected.\nWith `RDF`, the default forward is +Z.\n\nThe frustum's \"up\" direction will be whichever axis is set to `U` (or the opposite of `D`).\nThis will match the negative Y direction of pixel space (all images are assumed to have xyz=RDF).\nWith `RDF`, the default is up is -Y.\n\nThe frustum's \"right\" direction will be whichever axis is set to `R` (or the opposite of `L`).\nThis will match the positive X direction of pixel space (all images are assumed to have xyz=RDF).\nWith `RDF`, the default right is +x.\n\nOther common formats are `RUB` (X=Right, Y=Up, Z=Back) and `FLU` (X=Forward, Y=Left, Z=Up).\n\nNOTE: setting this to something else than `RDF` (the default) will change the orientation of the camera frustum,\nand make the pinhole matrix not match up with the coordinate system of the pinhole entity.\n\nThe pinhole matrix (the `image_from_camera` argument) always project along the third (Z) axis,\nbut will be re-oriented to project along the forward axis of the `camera_xyz` argument.", is_required : false, }, ArchetypeFieldReflection { component_name : "rerun.components.ImagePlaneDistance".into(), display_name : "Image plane distance", docstring_md : @@ -1959,11 +1959,11 @@ fn generate_archetype_reflection() -> ArchetypeReflectionMap { false, }, ArchetypeFieldReflection { component_name : "rerun.blueprint.components.GridSpacing".into(), display_name : "Spacing", docstring_md : - "Space between grid lines spacing of one line to the next in scene units.", + "Space between grid lines spacing of one line to the next in scene units.\n\nAs you zoom out, successively only every tenth line is shown.\nThis controls the closest zoom level.", is_required : false, }, ArchetypeFieldReflection { component_name : "rerun.components.Plane3D".into(), display_name : "Plane", docstring_md : - "In what plane the grid is drawn.\n\nDefaults to whatever plane is determined as the plane at zero units up/down as defined by [`archetype.ViewCoordinates`] if present.", + "In what plane the grid is drawn.\n\nDefaults to whatever plane is determined as the plane at zero units up/down as defined by [`components.ViewCoordinates`](https://rerun.io/docs/reference/types/components/view_coordinates) if present.", is_required : false, }, ArchetypeFieldReflection { component_name : "rerun.components.StrokeWidth".into(), display_name : "Stroke width", docstring_md : diff --git a/docs/content/reference/types/archetypes/instance_poses3d.md b/docs/content/reference/types/archetypes/instance_poses3d.md index 99ceac0f1243..5d3a488472b2 100644 --- a/docs/content/reference/types/archetypes/instance_poses3d.md +++ b/docs/content/reference/types/archetypes/instance_poses3d.md @@ -15,7 +15,7 @@ the 3x3 matrix is applied first, followed by the translation. Currently, many visualizers support only a single instance transform per entity. Check archetype documentations for details - if not otherwise specified, only the first instance transform is applied. -Some visualizers like the mesh visualizer used for [`archetype.Mesh3D`], +Some visualizers like the mesh visualizer used for [`archetype.Mesh3D`](https://rerun.io/docs/reference/types/archetype/mesh3d), will draw an object for every pose, a behavior also known as "instancing". ## Components diff --git a/docs/content/reference/types/components/plane3d.md b/docs/content/reference/types/components/plane3d.md index 320375107cd6..bdb085650e7a 100644 --- a/docs/content/reference/types/components/plane3d.md +++ b/docs/content/reference/types/components/plane3d.md @@ -5,7 +5,8 @@ title: "Plane3D" An infinite 3D plane represented by a unit normal vector and a distance. -Any point P on the plane fulfills the equation `dot(xyz, P) - d = 0`, where `xyz` is the plane's normal and `d` the distance. +Any point P on the plane fulfills the equation `dot(xyz, P) - d = 0`, +where `xyz` is the plane's normal and `d` the distance of the plane from the origin. This representation is also known as the Hesse normal form. Note: although the normal will be passed through to the diff --git a/docs/content/reference/types/datatypes/plane3d.md b/docs/content/reference/types/datatypes/plane3d.md index b74bf18af515..9f9e45a7f47c 100644 --- a/docs/content/reference/types/datatypes/plane3d.md +++ b/docs/content/reference/types/datatypes/plane3d.md @@ -5,7 +5,8 @@ title: "Plane3D" An infinite 3D plane represented by a unit normal vector and a distance. -Any point P on the plane fulfills the equation `dot(xyz, P) - d = 0`, where `xyz` is the plane's normal and `d` the distance. +Any point P on the plane fulfills the equation `dot(xyz, P) - d = 0`, +where `xyz` is the plane's normal and `d` the distance of the plane from the origin. This representation is also known as the Hesse normal form. Note: although the normal will be passed through to the diff --git a/docs/snippets/all/views/spatial3d.py b/docs/snippets/all/views/spatial3d.py index 8a1adb18a271..e1a146ea5248 100644 --- a/docs/snippets/all/views/spatial3d.py +++ b/docs/snippets/all/views/spatial3d.py @@ -22,6 +22,15 @@ name="3D Scene", # Set the background color to light blue. background=[100, 149, 237], + # Configure the line grid. + line_grid=rrb.archetypes.LineGrid3D( + visible=True, # The grid is enabled by default, but you can hide it with this property. + spacing=0.1, # Makes the grid more fine-grained. + # By default, the plane is inferred from view coordinates setup, but you can set arbitrary planes. + plane=rr.components.Plane3D((0, 0, 1), -5.0), + stroke_width=2.0, # Makes the grid lines twice as thick as usual. + color=[255, 255, 255, 128], # Colors the grid a half-transparent white. + ), ), collapse_panels=True, ) diff --git a/rerun_cpp/src/rerun/archetypes/instance_poses3d.hpp b/rerun_cpp/src/rerun/archetypes/instance_poses3d.hpp index 3bfc4c2292f2..69e7c9cf012f 100644 --- a/rerun_cpp/src/rerun/archetypes/instance_poses3d.hpp +++ b/rerun_cpp/src/rerun/archetypes/instance_poses3d.hpp @@ -32,7 +32,7 @@ namespace rerun::archetypes { /// /// Currently, many visualizers support only a single instance transform per entity. /// Check archetype documentations for details - if not otherwise specified, only the first instance transform is applied. - /// Some visualizers like the mesh visualizer used for [`archetype.Mesh3D`], + /// Some visualizers like the mesh visualizer used for `archetype::Mesh3D`, /// will draw an object for every pose, a behavior also known as "instancing". /// /// ## Example diff --git a/rerun_cpp/src/rerun/archetypes/pinhole.hpp b/rerun_cpp/src/rerun/archetypes/pinhole.hpp index 9b8486706602..61da282b23c3 100644 --- a/rerun_cpp/src/rerun/archetypes/pinhole.hpp +++ b/rerun_cpp/src/rerun/archetypes/pinhole.hpp @@ -92,7 +92,7 @@ namespace rerun::archetypes { /// Sets the view coordinates for the camera. /// - /// All common values are available as constants on the `components.ViewCoordinates` class. + /// All common values are available as constants on the `components::ViewCoordinates` class. /// /// The default is `ViewCoordinates::RDF`, i.e. X=Right, Y=Down, Z=Forward, and this is also the recommended setting. /// This means that the camera frustum will point along the positive Z axis of the parent space, @@ -208,7 +208,7 @@ namespace rerun::archetypes { /// Sets the view coordinates for the camera. /// - /// All common values are available as constants on the `components.ViewCoordinates` class. + /// All common values are available as constants on the `components::ViewCoordinates` class. /// /// The default is `ViewCoordinates::RDF`, i.e. X=Right, Y=Down, Z=Forward, and this is also the recommended setting. /// This means that the camera frustum will point along the positive Z axis of the parent space, diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.hpp b/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.hpp index 14df2133ee4f..0b57b2824edf 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.hpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.hpp @@ -28,11 +28,14 @@ namespace rerun::blueprint::archetypes { std::optional visible; /// Space between grid lines spacing of one line to the next in scene units. + /// + /// As you zoom out, successively only every tenth line is shown. + /// This controls the closest zoom level. std::optional spacing; /// In what plane the grid is drawn. /// - /// Defaults to whatever plane is determined as the plane at zero units up/down as defined by [`archetype.ViewCoordinates`] if present. + /// Defaults to whatever plane is determined as the plane at zero units up/down as defined by `components::ViewCoordinates` if present. std::optional plane; /// How thick the lines should be in ui units. @@ -67,6 +70,9 @@ namespace rerun::blueprint::archetypes { } /// Space between grid lines spacing of one line to the next in scene units. + /// + /// As you zoom out, successively only every tenth line is shown. + /// This controls the closest zoom level. LineGrid3D with_spacing(rerun::blueprint::components::GridSpacing _spacing) && { spacing = std::move(_spacing); // See: https://github.com/rerun-io/rerun/issues/4027 @@ -75,7 +81,7 @@ namespace rerun::blueprint::archetypes { /// In what plane the grid is drawn. /// - /// Defaults to whatever plane is determined as the plane at zero units up/down as defined by [`archetype.ViewCoordinates`] if present. + /// Defaults to whatever plane is determined as the plane at zero units up/down as defined by `components::ViewCoordinates` if present. LineGrid3D with_plane(rerun::components::Plane3D _plane) && { plane = std::move(_plane); // See: https://github.com/rerun-io/rerun/issues/4027 diff --git a/rerun_cpp/src/rerun/components/plane3d.hpp b/rerun_cpp/src/rerun/components/plane3d.hpp index 77308aad034c..431226ab80fd 100644 --- a/rerun_cpp/src/rerun/components/plane3d.hpp +++ b/rerun_cpp/src/rerun/components/plane3d.hpp @@ -12,7 +12,8 @@ namespace rerun::components { /// **Component**: An infinite 3D plane represented by a unit normal vector and a distance. /// - /// Any point P on the plane fulfills the equation `dot(xyz, P) - d = 0`, where `xyz` is the plane's normal and `d` the distance. + /// Any point P on the plane fulfills the equation `dot(xyz, P) - d = 0`, + /// where `xyz` is the plane's normal and `d` the distance of the plane from the origin. /// This representation is also known as the Hesse normal form. /// /// Note: although the normal will be passed through to the diff --git a/rerun_cpp/src/rerun/datatypes/plane3d.hpp b/rerun_cpp/src/rerun/datatypes/plane3d.hpp index 4e6797245324..4f3da86993d4 100644 --- a/rerun_cpp/src/rerun/datatypes/plane3d.hpp +++ b/rerun_cpp/src/rerun/datatypes/plane3d.hpp @@ -18,7 +18,8 @@ namespace arrow { namespace rerun::datatypes { /// **Datatype**: An infinite 3D plane represented by a unit normal vector and a distance. /// - /// Any point P on the plane fulfills the equation `dot(xyz, P) - d = 0`, where `xyz` is the plane's normal and `d` the distance. + /// Any point P on the plane fulfills the equation `dot(xyz, P) - d = 0`, + /// where `xyz` is the plane's normal and `d` the distance of the plane from the origin. /// This representation is also known as the Hesse normal form. /// /// Note: although the normal will be passed through to the diff --git a/rerun_py/rerun_sdk/rerun/archetypes/instance_poses3d.py b/rerun_py/rerun_sdk/rerun/archetypes/instance_poses3d.py index 80fc89d76d1f..e431d6afa73c 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/instance_poses3d.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/instance_poses3d.py @@ -33,7 +33,7 @@ class InstancePoses3D(Archetype): Currently, many visualizers support only a single instance transform per entity. Check archetype documentations for details - if not otherwise specified, only the first instance transform is applied. - Some visualizers like the mesh visualizer used for [`archetype.Mesh3D`], + Some visualizers like the mesh visualizer used for [`archetype.Mesh3D`][rerun.archetype.Mesh3D], will draw an object for every pose, a behavior also known as "instancing". Example diff --git a/rerun_py/rerun_sdk/rerun/archetypes/pinhole.py b/rerun_py/rerun_sdk/rerun/archetypes/pinhole.py index 8facb8bd7048..b32c37db390a 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/pinhole.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/pinhole.py @@ -119,7 +119,7 @@ def _clear(cls) -> Pinhole: ) # Sets the view coordinates for the camera. # - # All common values are available as constants on the `components.ViewCoordinates` class. + # All common values are available as constants on the [`components.ViewCoordinates`][rerun.components.ViewCoordinates] class. # # The default is `ViewCoordinates::RDF`, i.e. X=Right, Y=Down, Z=Forward, and this is also the recommended setting. # This means that the camera frustum will point along the positive Z axis of the parent space, diff --git a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/line_grid3d.py b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/line_grid3d.py index 2422169539ce..29e679f10344 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/line_grid3d.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/line_grid3d.py @@ -43,10 +43,13 @@ def __init__( Defaults to true. spacing: Space between grid lines spacing of one line to the next in scene units. + + As you zoom out, successively only every tenth line is shown. + This controls the closest zoom level. plane: In what plane the grid is drawn. - Defaults to whatever plane is determined as the plane at zero units up/down as defined by [`archetype.ViewCoordinates`] if present. + Defaults to whatever plane is determined as the plane at zero units up/down as defined by [`components.ViewCoordinates`][rerun.components.ViewCoordinates] if present. stroke_width: How thick the lines should be in ui units. @@ -100,6 +103,9 @@ def _clear(cls) -> LineGrid3D: ) # Space between grid lines spacing of one line to the next in scene units. # + # As you zoom out, successively only every tenth line is shown. + # This controls the closest zoom level. + # # (Docstring intentionally commented out to hide this field from the docs) plane: components.Plane3DBatch | None = field( @@ -109,7 +115,7 @@ def _clear(cls) -> LineGrid3D: ) # In what plane the grid is drawn. # - # Defaults to whatever plane is determined as the plane at zero units up/down as defined by [`archetype.ViewCoordinates`] if present. + # Defaults to whatever plane is determined as the plane at zero units up/down as defined by [`components.ViewCoordinates`][rerun.components.ViewCoordinates] if present. # # (Docstring intentionally commented out to hide this field from the docs) diff --git a/rerun_py/rerun_sdk/rerun/blueprint/views/spatial3d_view.py b/rerun_py/rerun_sdk/rerun/blueprint/views/spatial3d_view.py index a880cde684bd..9f157eb51b9a 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/views/spatial3d_view.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/views/spatial3d_view.py @@ -45,6 +45,15 @@ class Spatial3DView(SpaceView): name="3D Scene", # Set the background color to light blue. background=[100, 149, 237], + # Configure the line grid. + line_grid=rrb.archetypes.LineGrid3D( + visible=True, # The grid is enabled by default, but you can hide it with this property. + spacing=0.1, # Makes the grid more fine-grained. + # By default, the plane is inferred from view coordinates setup, but you can set arbitrary planes. + plane=rr.components.Plane3D((0, 0, 1), -5.0), + stroke_width=2.0, # Makes the grid lines twice as thick as usual. + color=[255, 255, 255, 128], # Colors the grid a half-transparent white. + ), ), collapse_panels=True, ) diff --git a/rerun_py/rerun_sdk/rerun/components/plane3d.py b/rerun_py/rerun_sdk/rerun/components/plane3d.py index 72a6b42517ad..7423979f2ebe 100644 --- a/rerun_py/rerun_sdk/rerun/components/plane3d.py +++ b/rerun_py/rerun_sdk/rerun/components/plane3d.py @@ -18,7 +18,8 @@ class Plane3D(datatypes.Plane3D, ComponentMixin): """ **Component**: An infinite 3D plane represented by a unit normal vector and a distance. - Any point P on the plane fulfills the equation `dot(xyz, P) - d = 0`, where `xyz` is the plane's normal and `d` the distance. + Any point P on the plane fulfills the equation `dot(xyz, P) - d = 0`, + where `xyz` is the plane's normal and `d` the distance of the plane from the origin. This representation is also known as the Hesse normal form. Note: although the normal will be passed through to the diff --git a/rerun_py/rerun_sdk/rerun/datatypes/plane3d.py b/rerun_py/rerun_sdk/rerun/datatypes/plane3d.py index 0c2f818194cd..6bfd4c5151cb 100644 --- a/rerun_py/rerun_sdk/rerun/datatypes/plane3d.py +++ b/rerun_py/rerun_sdk/rerun/datatypes/plane3d.py @@ -18,16 +18,18 @@ from .._converters import ( to_np_float32, ) +from .plane3d_ext import Plane3DExt __all__ = ["Plane3D", "Plane3DArrayLike", "Plane3DBatch", "Plane3DLike"] @define(init=False) -class Plane3D: +class Plane3D(Plane3DExt): """ **Datatype**: An infinite 3D plane represented by a unit normal vector and a distance. - Any point P on the plane fulfills the equation `dot(xyz, P) - d = 0`, where `xyz` is the plane's normal and `d` the distance. + Any point P on the plane fulfills the equation `dot(xyz, P) - d = 0`, + where `xyz` is the plane's normal and `d` the distance of the plane from the origin. This representation is also known as the Hesse normal form. Note: although the normal will be passed through to the @@ -35,11 +37,7 @@ class Plane3D: I.e. the plane with xyz = (2, 0, 0), d = 1 is equivalent to xyz = (1, 0, 0), d = 0.5 """ - def __init__(self: Any, xyzd: Plane3DLike): - """Create a new instance of the Plane3D datatype.""" - - # You can define your own __init__ function as a member of Plane3DExt in plane3d_ext.py - self.__attrs_init__(xyzd=xyzd) + # __init__ can be found in plane3d_ext.py xyzd: npt.NDArray[np.float32] = field(converter=to_np_float32) @@ -57,6 +55,7 @@ class Plane3DBatch(BaseBatch[Plane3DArrayLike]): @staticmethod def _native_to_pa_array(data: Plane3DArrayLike, data_type: pa.DataType) -> pa.Array: - raise NotImplementedError( - "Arrow serialization of Plane3D not implemented: We lack codegen for arrow-serialization of general structs" - ) # You need to implement native_to_pa_array_override in plane3d_ext.py + return Plane3DExt.native_to_pa_array_override(data, data_type) + + +Plane3DExt.deferred_patch_class(Plane3D) diff --git a/rerun_py/rerun_sdk/rerun/datatypes/plane3d_ext.py b/rerun_py/rerun_sdk/rerun/datatypes/plane3d_ext.py new file mode 100644 index 000000000000..0fc1ded09185 --- /dev/null +++ b/rerun_py/rerun_sdk/rerun/datatypes/plane3d_ext.py @@ -0,0 +1,59 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING, Any, Union + +import numpy as np +import pyarrow as pa + +from .._validators import flat_np_float32_array_from_array_like + +if TYPE_CHECKING: + from . import Plane3D, Plane3DArrayLike, Vec3DLike + + +class Plane3DExt: + """Extension for [Plane3D][rerun.datatypes.Plane3D].""" + + # The Y^Z plane with normal = +X. + YZ: Plane3D = None # type: ignore[assignment] + + # The Z^X plane with normal = +Y. + ZX: Plane3D = None # type: ignore[assignment] + + # The X^Y plane with normal = +Z. + XY: Plane3D = None # type: ignore[assignment] + + @staticmethod + def deferred_patch_class(cls: Any) -> None: + cls.YZ = cls([1.0, 0.0, 0.0]) + cls.ZX = cls([0.0, 1.0, 0.0]) + cls.XY = cls([0.0, 0.0, 1.0]) + + def __init__(self: Any, normal: Vec3DLike, distance: Union[float, int, None] = None) -> None: + """ + Create a new instance of the Plane3D datatype. + + Does *not* normalize the plane. + + Parameters + ---------- + normal: + Normal vector of the plane. + distance: + Distance of the plane from the origin. + Defaults to zero. + + """ + + normal_np = flat_np_float32_array_from_array_like(normal, 3) + if distance is None: + distance_np = np.array([0.0], dtype=np.float32) + else: + distance_np = np.array([distance], dtype=np.float32) + + self.__attrs_init__(xyzd=np.concatenate((normal_np, distance_np))) + + @staticmethod + def native_to_pa_array_override(data: Plane3DArrayLike, data_type: pa.DataType) -> pa.Array: + planes = flat_np_float32_array_from_array_like(data, 4) + return pa.FixedSizeListArray.from_arrays(planes, type=data_type) From 87aff22f6519409aadbc67959c9f9d9e1a32e79f Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Tue, 3 Dec 2024 19:22:01 +0100 Subject: [PATCH 22/29] fix botched link fix --- .../re_types/definitions/rerun/archetypes/instance_poses3d.fbs | 2 +- crates/store/re_types/src/archetypes/instance_poses3d.rs | 2 +- docs/content/reference/types/archetypes/instance_poses3d.md | 2 +- rerun_cpp/src/rerun/archetypes/instance_poses3d.hpp | 2 +- rerun_py/rerun_sdk/rerun/archetypes/instance_poses3d.py | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/store/re_types/definitions/rerun/archetypes/instance_poses3d.fbs b/crates/store/re_types/definitions/rerun/archetypes/instance_poses3d.fbs index 4578e5668f85..d7ffbabe01ea 100644 --- a/crates/store/re_types/definitions/rerun/archetypes/instance_poses3d.fbs +++ b/crates/store/re_types/definitions/rerun/archetypes/instance_poses3d.fbs @@ -13,7 +13,7 @@ namespace rerun.archetypes; /// /// Currently, many visualizers support only a single instance transform per entity. /// Check archetype documentations for details - if not otherwise specified, only the first instance transform is applied. -/// Some visualizers like the mesh visualizer used for [archetype.Mesh3D], +/// Some visualizers like the mesh visualizer used for [archetypes.Mesh3D], /// will draw an object for every pose, a behavior also known as "instancing". /// /// \example archetypes/instance_poses3d_combined title="Regular & instance transforms in tandem" image="https://static.rerun.io/leaf_transform3d/41674f0082d6de489f8a1cd1583f60f6b5820ddf/1200w.png" diff --git a/crates/store/re_types/src/archetypes/instance_poses3d.rs b/crates/store/re_types/src/archetypes/instance_poses3d.rs index 530eb5da6f1f..08afec086b9e 100644 --- a/crates/store/re_types/src/archetypes/instance_poses3d.rs +++ b/crates/store/re_types/src/archetypes/instance_poses3d.rs @@ -30,7 +30,7 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; /// /// Currently, many visualizers support only a single instance transform per entity. /// Check archetype documentations for details - if not otherwise specified, only the first instance transform is applied. -/// Some visualizers like the mesh visualizer used for [`archetype::Mesh3D`][crate::archetype::Mesh3D], +/// Some visualizers like the mesh visualizer used for [`archetypes::Mesh3D`][crate::archetypes::Mesh3D], /// will draw an object for every pose, a behavior also known as "instancing". /// /// ## Example diff --git a/docs/content/reference/types/archetypes/instance_poses3d.md b/docs/content/reference/types/archetypes/instance_poses3d.md index 5d3a488472b2..89f7e9846421 100644 --- a/docs/content/reference/types/archetypes/instance_poses3d.md +++ b/docs/content/reference/types/archetypes/instance_poses3d.md @@ -15,7 +15,7 @@ the 3x3 matrix is applied first, followed by the translation. Currently, many visualizers support only a single instance transform per entity. Check archetype documentations for details - if not otherwise specified, only the first instance transform is applied. -Some visualizers like the mesh visualizer used for [`archetype.Mesh3D`](https://rerun.io/docs/reference/types/archetype/mesh3d), +Some visualizers like the mesh visualizer used for [`archetypes.Mesh3D`](https://rerun.io/docs/reference/types/archetypes/mesh3d), will draw an object for every pose, a behavior also known as "instancing". ## Components diff --git a/rerun_cpp/src/rerun/archetypes/instance_poses3d.hpp b/rerun_cpp/src/rerun/archetypes/instance_poses3d.hpp index 69e7c9cf012f..f85c85c565f3 100644 --- a/rerun_cpp/src/rerun/archetypes/instance_poses3d.hpp +++ b/rerun_cpp/src/rerun/archetypes/instance_poses3d.hpp @@ -32,7 +32,7 @@ namespace rerun::archetypes { /// /// Currently, many visualizers support only a single instance transform per entity. /// Check archetype documentations for details - if not otherwise specified, only the first instance transform is applied. - /// Some visualizers like the mesh visualizer used for `archetype::Mesh3D`, + /// Some visualizers like the mesh visualizer used for `archetypes::Mesh3D`, /// will draw an object for every pose, a behavior also known as "instancing". /// /// ## Example diff --git a/rerun_py/rerun_sdk/rerun/archetypes/instance_poses3d.py b/rerun_py/rerun_sdk/rerun/archetypes/instance_poses3d.py index e431d6afa73c..0532c2968c76 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/instance_poses3d.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/instance_poses3d.py @@ -33,7 +33,7 @@ class InstancePoses3D(Archetype): Currently, many visualizers support only a single instance transform per entity. Check archetype documentations for details - if not otherwise specified, only the first instance transform is applied. - Some visualizers like the mesh visualizer used for [`archetype.Mesh3D`][rerun.archetype.Mesh3D], + Some visualizers like the mesh visualizer used for [`archetypes.Mesh3D`][rerun.archetypes.Mesh3D], will draw an object for every pose, a behavior also known as "instancing". Example From c078cba18bfd2f78bf42106371ae4ffd79731e00 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Thu, 5 Dec 2024 10:11:54 +0100 Subject: [PATCH 23/29] fix multiline uis not being indented --- crates/viewer/re_component_ui/src/marker_shape.rs | 3 ++- crates/viewer/re_component_ui/src/plane3d.rs | 6 ++++-- crates/viewer/re_component_ui/src/transforms.rs | 9 +++++---- crates/viewer/re_component_ui/src/visual_bounds2d.rs | 6 ++++-- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/crates/viewer/re_component_ui/src/marker_shape.rs b/crates/viewer/re_component_ui/src/marker_shape.rs index b55c474d3d6e..5c08682ee1f4 100644 --- a/crates/viewer/re_component_ui/src/marker_shape.rs +++ b/crates/viewer/re_component_ui/src/marker_shape.rs @@ -55,7 +55,8 @@ pub(crate) fn edit_marker_shape_ui( ) } else { let marker: MarkerShape = *marker.as_ref(); - ui.list_item_flat_noninteractive( + ui.list_item().interactive(false).show_hierarchical( + ui, re_ui::list_item::LabelContent::new(marker.to_string()) .min_desired_width(item_width) .with_icon_fn(|ui, rect, visuals| { diff --git a/crates/viewer/re_component_ui/src/plane3d.rs b/crates/viewer/re_component_ui/src/plane3d.rs index 5bbd4323d0e3..20b9210d08b6 100644 --- a/crates/viewer/re_component_ui/src/plane3d.rs +++ b/crates/viewer/re_component_ui/src/plane3d.rs @@ -127,7 +127,8 @@ pub fn multiline_edit_or_view_plane3d( ) -> egui::Response { let mut any_edit = false; - let response_normal = ui.list_item_flat_noninteractive( + let response_normal = ui.list_item().interactive(false).show_hierarchical( + ui, re_ui::list_item::PropertyContent::new("Normal").value_fn(|ui, _| { let mut normal = value.normal(); let mut maybe_mut_normal = match value { @@ -143,7 +144,8 @@ pub fn multiline_edit_or_view_plane3d( }), ); - let response_distance = ui.list_item_flat_noninteractive( + let response_distance = ui.list_item().interactive(false).show_hierarchical( + ui, re_ui::list_item::PropertyContent::new("Distance").value_fn(|ui, _| { let mut maybe_mut_distance = match value { MaybeMutRef::Ref(value) => MaybeMutRef::Ref(&value.0 .0[3]), diff --git a/crates/viewer/re_component_ui/src/transforms.rs b/crates/viewer/re_component_ui/src/transforms.rs index 17ff1b0346f0..5312470215ca 100644 --- a/crates/viewer/re_component_ui/src/transforms.rs +++ b/crates/viewer/re_component_ui/src/transforms.rs @@ -23,8 +23,9 @@ pub fn multiline_view_transform_mat3x3( let col1 = value.0.col(1); let col2 = value.0.col(2); - ui.list_item_flat_noninteractive(re_ui::list_item::PropertyContent::new("matrix").value_fn( - |ui, _| { + ui.list_item().interactive(false).show_hierarchical( + ui, + re_ui::list_item::PropertyContent::new("matrix").value_fn(|ui, _| { egui::Grid::new("matrix").num_columns(3).show(ui, |ui| { ui.monospace(re_format::format_f32(col0[0])); ui.monospace(re_format::format_f32(col1[0])); @@ -41,6 +42,6 @@ pub fn multiline_view_transform_mat3x3( ui.monospace(re_format::format_f32(col2[2])); ui.end_row(); }); - }, - )) + }), + ) } diff --git a/crates/viewer/re_component_ui/src/visual_bounds2d.rs b/crates/viewer/re_component_ui/src/visual_bounds2d.rs index 47c1a121e9c1..dea74164070e 100644 --- a/crates/viewer/re_component_ui/src/visual_bounds2d.rs +++ b/crates/viewer/re_component_ui/src/visual_bounds2d.rs @@ -11,7 +11,8 @@ pub fn multiline_edit_visual_bounds2d( ) -> egui::Response { let mut any_edit = false; - let response_x = ui.list_item_flat_noninteractive( + let response_x = ui.list_item().interactive(false).show_hierarchical( + ui, re_ui::list_item::PropertyContent::new("x").value_fn(|ui, _| { if let Some(value) = value.as_mut() { any_edit |= range_mut_ui(ui, &mut value.x_range.0).changed(); @@ -21,7 +22,8 @@ pub fn multiline_edit_visual_bounds2d( }), ); - let response_y = ui.list_item_flat_noninteractive( + let response_y = ui.list_item().interactive(false).show_hierarchical( + ui, re_ui::list_item::PropertyContent::new("y").value_fn(|ui, _| { if let Some(value) = value.as_mut() { any_edit |= range_mut_ui(ui, &mut value.y_range.0).changed(); From b4ef81cf5440dee6774fc89673d315ed7835e312 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Thu, 5 Dec 2024 10:40:37 +0100 Subject: [PATCH 24/29] fix plane3d use in check_all_components_ui --- tests/python/release_checklist/check_all_components_ui.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/python/release_checklist/check_all_components_ui.py b/tests/python/release_checklist/check_all_components_ui.py index e9f484296bcd..b9106703631f 100644 --- a/tests/python/release_checklist/check_all_components_ui.py +++ b/tests/python/release_checklist/check_all_components_ui.py @@ -184,7 +184,7 @@ def alternatives(self) -> list[Any] | None: "NameBatch": TestCase(batch=["Hello World", "Foo Bar", "Baz Qux"]), "OpacityBatch": TestCase(0.5), "PinholeProjectionBatch": TestCase([(0, 1, 2), (3, 4, 5), (6, 7, 8)]), - "Plane3DBatch": TestCase(rr.datatypes.Plane3D(xyzd=(1, 2, 3, 4))), + "Plane3DBatch": TestCase(rr.datatypes.Plane3D(normal=(1, 2, 3), distance=4)), "PoseRotationAxisAngleBatch": TestCase( rr.datatypes.RotationAxisAngle(axis=(1, 0, 0), angle=rr.datatypes.Angle(rad=math.pi)) ), From 472b84a947ca2f112bbc25e2b38d03c8b9c28124 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Thu, 5 Dec 2024 10:57:14 +0100 Subject: [PATCH 25/29] improved plane3d ui --- crates/viewer/re_component_ui/src/plane3d.rs | 100 ++++++++++--------- 1 file changed, 53 insertions(+), 47 deletions(-) diff --git a/crates/viewer/re_component_ui/src/plane3d.rs b/crates/viewer/re_component_ui/src/plane3d.rs index 20b9210d08b6..2b3484f60e19 100644 --- a/crates/viewer/re_component_ui/src/plane3d.rs +++ b/crates/viewer/re_component_ui/src/plane3d.rs @@ -15,6 +15,9 @@ enum AxisDirection { NegX, NegY, NegZ, + + /// Not along any axis. + Other, } impl AxisDirection { @@ -37,35 +40,37 @@ impl std::fmt::Display for AxisDirection { Self::NegX => write!(f, "-X"), Self::NegY => write!(f, "-Y"), Self::NegZ => write!(f, "-Z"), + Self::Other => write!(f, "-"), } } } -impl TryFrom for AxisDirection { - type Error = (); - - fn try_from(value: glam::Vec3) -> Result { +impl From for AxisDirection { + fn from(value: glam::Vec3) -> Self { match value { - glam::Vec3::X => Ok(Self::PosX), - glam::Vec3::Y => Ok(Self::PosY), - glam::Vec3::Z => Ok(Self::PosZ), - glam::Vec3::NEG_X => Ok(Self::NegX), - glam::Vec3::NEG_Y => Ok(Self::NegY), - glam::Vec3::NEG_Z => Ok(Self::NegZ), - _ => Err(()), + glam::Vec3::X => Self::PosX, + glam::Vec3::Y => Self::PosY, + glam::Vec3::Z => Self::PosZ, + glam::Vec3::NEG_X => Self::NegX, + glam::Vec3::NEG_Y => Self::NegY, + glam::Vec3::NEG_Z => Self::NegZ, + _ => Self::Other, } } } -impl From for glam::Vec3 { - fn from(value: AxisDirection) -> Self { +impl TryFrom for glam::Vec3 { + type Error = (); + + fn try_from(value: AxisDirection) -> Result { match value { - AxisDirection::PosX => Self::X, - AxisDirection::PosY => Self::Y, - AxisDirection::PosZ => Self::Z, - AxisDirection::NegX => Self::NEG_X, - AxisDirection::NegY => Self::NEG_Y, - AxisDirection::NegZ => Self::NEG_Z, + AxisDirection::PosX => Ok(Self::X), + AxisDirection::PosY => Ok(Self::Y), + AxisDirection::PosZ => Ok(Self::Z), + AxisDirection::NegX => Ok(Self::NEG_X), + AxisDirection::NegY => Ok(Self::NEG_Y), + AxisDirection::NegZ => Ok(Self::NEG_Z), + AxisDirection::Other => Err(()), } } } @@ -79,35 +84,36 @@ pub fn edit_or_view_plane3d( ui.label("n"); // Show simplified combobox if this is axis aligned. - let normal_response = if let Ok(mut axis_dir) = - AxisDirection::try_from(glam::Vec3::from(value.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 MaybeMutRef::MutRef(value) = value { - **value = components::Plane3D::new(glam::Vec3::from(axis_dir), distance); + 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 { + if let Ok(new_dir) = glam::Vec3::try_from(axis_dir) { + **value = components::Plane3D::new(new_dir, distance); } - response - }), - ) - } else { - // Editing for arbitrary normals takes too much space here. - edit_or_view_vec3d_raw(ui, &mut MaybeMutRef::Ref(&value.normal())) - }; + } + 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()), + )); ui.label("d"); let mut maybe_mut_distance = match value { From 6edb4f0ee8968c95a1dc5b8494659bfacbe85bb5 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Thu, 5 Dec 2024 11:04:24 +0100 Subject: [PATCH 26/29] rename line_grid3d file --- .../store/re_types/definitions/rerun/blueprint/archetypes.fbs | 2 +- .../blueprint/archetypes/{line_grid_3d.fbs => line_grid3d.fbs} | 0 crates/store/re_types/src/blueprint/archetypes/line_grid3d.rs | 2 +- rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.cpp | 2 +- rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.hpp | 2 +- rerun_py/rerun_sdk/rerun/blueprint/archetypes/line_grid3d.py | 2 +- 6 files changed, 5 insertions(+), 5 deletions(-) rename crates/store/re_types/definitions/rerun/blueprint/archetypes/{line_grid_3d.fbs => line_grid3d.fbs} (100%) diff --git a/crates/store/re_types/definitions/rerun/blueprint/archetypes.fbs b/crates/store/re_types/definitions/rerun/blueprint/archetypes.fbs index 7ca46166ee56..448b93b16a60 100644 --- a/crates/store/re_types/definitions/rerun/blueprint/archetypes.fbs +++ b/crates/store/re_types/definitions/rerun/blueprint/archetypes.fbs @@ -3,7 +3,7 @@ include "./archetypes/background.fbs"; include "./archetypes/container_blueprint.fbs"; include "./archetypes/dataframe_query.fbs"; -include "./archetypes/line_grid_3d.fbs"; +include "./archetypes/line_grid3d.fbs"; include "./archetypes/map_background.fbs"; include "./archetypes/map_zoom.fbs"; include "./archetypes/panel_blueprint.fbs"; diff --git a/crates/store/re_types/definitions/rerun/blueprint/archetypes/line_grid_3d.fbs b/crates/store/re_types/definitions/rerun/blueprint/archetypes/line_grid3d.fbs similarity index 100% rename from crates/store/re_types/definitions/rerun/blueprint/archetypes/line_grid_3d.fbs rename to crates/store/re_types/definitions/rerun/blueprint/archetypes/line_grid3d.fbs diff --git a/crates/store/re_types/src/blueprint/archetypes/line_grid3d.rs b/crates/store/re_types/src/blueprint/archetypes/line_grid3d.rs index b594d2176086..a5121afe618c 100644 --- a/crates/store/re_types/src/blueprint/archetypes/line_grid3d.rs +++ b/crates/store/re_types/src/blueprint/archetypes/line_grid3d.rs @@ -1,5 +1,5 @@ // 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/blueprint/archetypes/line_grid_3d.fbs". +// Based on "crates/store/re_types/definitions/rerun/blueprint/archetypes/line_grid3d.fbs". #![allow(unused_imports)] #![allow(unused_parens)] diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.cpp b/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.cpp index d1524ed49629..c7661a7cd130 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.cpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.cpp @@ -1,5 +1,5 @@ // 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/blueprint/archetypes/line_grid_3d.fbs". +// Based on "crates/store/re_types/definitions/rerun/blueprint/archetypes/line_grid3d.fbs". #include "line_grid3d.hpp" diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.hpp b/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.hpp index 0b57b2824edf..6cc5e342dc38 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.hpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.hpp @@ -1,5 +1,5 @@ // 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/blueprint/archetypes/line_grid_3d.fbs". +// Based on "crates/store/re_types/definitions/rerun/blueprint/archetypes/line_grid3d.fbs". #pragma once diff --git a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/line_grid3d.py b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/line_grid3d.py index 29e679f10344..a34c8f217b9c 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/line_grid3d.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/line_grid3d.py @@ -1,5 +1,5 @@ # 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/blueprint/archetypes/line_grid_3d.fbs". +# Based on "crates/store/re_types/definitions/rerun/blueprint/archetypes/line_grid3d.fbs". # You can extend this class by creating a "LineGrid3DExt" class in "line_grid3d_ext.py". From 3cdbed5741c8a8352d5584d8e21b4ff7f4dc528c Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Fri, 6 Dec 2024 10:35:42 +0100 Subject: [PATCH 27/29] better plane init in python --- docs/snippets/all/views/spatial3d.py | 2 +- .../rerun_sdk/rerun/datatypes/plane3d_ext.py | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/docs/snippets/all/views/spatial3d.py b/docs/snippets/all/views/spatial3d.py index e1a146ea5248..714d228976d9 100644 --- a/docs/snippets/all/views/spatial3d.py +++ b/docs/snippets/all/views/spatial3d.py @@ -27,7 +27,7 @@ visible=True, # The grid is enabled by default, but you can hide it with this property. spacing=0.1, # Makes the grid more fine-grained. # By default, the plane is inferred from view coordinates setup, but you can set arbitrary planes. - plane=rr.components.Plane3D((0, 0, 1), -5.0), + plane=rr.components.Plane3D.XY.with_distance(-5.0), stroke_width=2.0, # Makes the grid lines twice as thick as usual. color=[255, 255, 255, 128], # Colors the grid a half-transparent white. ), diff --git a/rerun_py/rerun_sdk/rerun/datatypes/plane3d_ext.py b/rerun_py/rerun_sdk/rerun/datatypes/plane3d_ext.py index 0fc1ded09185..11c4859c11ba 100644 --- a/rerun_py/rerun_sdk/rerun/datatypes/plane3d_ext.py +++ b/rerun_py/rerun_sdk/rerun/datatypes/plane3d_ext.py @@ -1,8 +1,9 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any, Union +from typing import TYPE_CHECKING, Any, Union, cast import numpy as np +import numpy.typing as npt import pyarrow as pa from .._validators import flat_np_float32_array_from_array_like @@ -53,6 +54,20 @@ def __init__(self: Any, normal: Vec3DLike, distance: Union[float, int, None] = N self.__attrs_init__(xyzd=np.concatenate((normal_np, distance_np))) + def normal(self: Any) -> npt.NDArray[np.float32]: + """Returns the normal vector of the plane.""" + return cast(npt.NDArray[np.float32], self.xyzd[:3]) + + def distance(self: Any) -> float: + """Returns the distance of the plane from the origin.""" + return cast(float, self.xyzd[3]) + + def with_distance(self: Any, distance: float) -> Plane3D: + """Returns a new plane with the same normal but with the distance set to the given amount.""" + from . import Plane3D + + return Plane3D(self.normal(), distance) + @staticmethod def native_to_pa_array_override(data: Plane3DArrayLike, data_type: pa.DataType) -> pa.Array: planes = flat_np_float32_array_from_array_like(data, 4) From 103a6ab8e24b13d001a55a8e3224cf58a199462d Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Fri, 6 Dec 2024 10:36:00 +0100 Subject: [PATCH 28/29] comment on why custom grid3d view property --- crates/viewer/re_space_view_spatial/src/view_3d.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/viewer/re_space_view_spatial/src/view_3d.rs b/crates/viewer/re_space_view_spatial/src/view_3d.rs index 34fa52b4e617..3beb4cc28ff8 100644 --- a/crates/viewer/re_space_view_spatial/src/view_3d.rs +++ b/crates/viewer/re_space_view_spatial/src/view_3d.rs @@ -422,7 +422,6 @@ impl SpaceViewClass for SpatialSpaceView3D { re_ui::list_item::list_item_scope(ui, "spatial_view3d_selection_ui", |ui| { view_property_ui::(ctx, ui, view_id, self, state); - //view_property_ui::(ctx, ui, view_id, self, state); view_property_ui_grid3d(ctx, ui, view_id, self, state); }); @@ -447,6 +446,9 @@ impl SpaceViewClass for SpatialSpaceView3D { } } +// The generic ui (via `view_property_ui::(ctx, ui, view_id, self, state);`) +// is suitable for the most part. However, as of writing the alpha color picker doesn't handle alpha +// which we need here. fn view_property_ui_grid3d( ctx: &ViewerContext<'_>, ui: &mut egui::Ui, From 487412c20ffd022157977a458ad8f3715d752b30 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Fri, 6 Dec 2024 11:14:35 +0100 Subject: [PATCH 29/29] codegen harder --- rerun_py/rerun_sdk/rerun/blueprint/views/spatial3d_view.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rerun_py/rerun_sdk/rerun/blueprint/views/spatial3d_view.py b/rerun_py/rerun_sdk/rerun/blueprint/views/spatial3d_view.py index 9f157eb51b9a..0fac6a2391d2 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/views/spatial3d_view.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/views/spatial3d_view.py @@ -50,7 +50,7 @@ class Spatial3DView(SpaceView): visible=True, # The grid is enabled by default, but you can hide it with this property. spacing=0.1, # Makes the grid more fine-grained. # By default, the plane is inferred from view coordinates setup, but you can set arbitrary planes. - plane=rr.components.Plane3D((0, 0, 1), -5.0), + plane=rr.components.Plane3D.XY.with_distance(-5.0), stroke_width=2.0, # Makes the grid lines twice as thick as usual. color=[255, 255, 255, 128], # Colors the grid a half-transparent white. ),