Skip to content

Commit

Permalink
Introduce new archetype for Axes3D (#6510)
Browse files Browse the repository at this point in the history
### What
- Builds on top of: #6505 (merge
that first and rebase)

This replaces the axes-related entity properties with a new Axes3D
archetype.

The archetype allows overriding the axis-length from code.
Controlling whether the axes are visible now happens via enabling of the
visualizer.

We use similar heuristics to before to enable axes3d visualizers on
transforms in certain situations.

The legacy UI has been remapped to the new indicator/heuristics
implementation.


![image](https://github.com/rerun-io/rerun/assets/3312232/e24bbe52-5470-41e1-ada6-79d0d8059cef)

TODO:
- [] Still need to implement the example in rust / cpp.

### Checklist
* [x] I have read and agree to [Contributor
Guide](https://github.com/rerun-io/rerun/blob/main/CONTRIBUTING.md) and
the [Code of
Conduct](https://github.com/rerun-io/rerun/blob/main/CODE_OF_CONDUCT.md)
* [x] I've included a screenshot or gif (if applicable)
* [x] I have tested the web demo (if applicable):
* Using examples from latest `main` build:
[rerun.io/viewer](https://rerun.io/viewer/pr/6510?manifest_url=https://app.rerun.io/version/main/examples_manifest.json)
* Using full set of examples from `nightly` build:
[rerun.io/viewer](https://rerun.io/viewer/pr/6510?manifest_url=https://app.rerun.io/version/nightly/examples_manifest.json)
* [x] The PR title and labels are set such as to maximize their
usefulness for the next release's CHANGELOG
* [x] If applicable, add a new check to the [release
checklist](https://github.com/rerun-io/rerun/blob/main/tests/python/release_checklist)!

- [PR Build Summary](https://build.rerun.io/pr/6510)
- [Recent benchmark results](https://build.rerun.io/graphs/crates.html)
- [Wasm size tracking](https://build.rerun.io/graphs/sizes.html)

To run all checks from `main`, comment on the PR with `@rerun-bot
full-check`.
  • Loading branch information
jleibs authored Jun 6, 2024
1 parent 0346905 commit 5a10357
Show file tree
Hide file tree
Showing 63 changed files with 1,461 additions and 314 deletions.
12 changes: 11 additions & 1 deletion crates/re_edit_ui/src/datatype_editors/float_drag.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
use egui::NumExt as _;
use re_types::datatypes;

/// Generic editor for a f32 value from zero to infinity.
/// Generic editor for a [`re_types::datatypes::Float32`] value from zero to infinity.
pub fn edit_f32_zero_to_inf(
_ctx: &re_viewer_context::ViewerContext<'_>,
ui: &mut egui::Ui,
value: &mut impl std::ops::DerefMut<Target = datatypes::Float32>,
) -> egui::Response {
edit_f32_zero_to_inf_impl(ui, &mut value.deref_mut().0)
}

/// Generic editor for a raw f32 value from zero to infinity.
pub fn edit_f32_zero_to_inf_raw(
_ctx: &re_viewer_context::ViewerContext<'_>,
ui: &mut egui::Ui,
value: &mut impl std::ops::DerefMut<Target = f32>,
Expand Down
2 changes: 1 addition & 1 deletion crates/re_edit_ui/src/datatype_editors/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ mod singleline_string;

pub use bool_toggle::{edit_bool, edit_bool_raw};
pub use enum_combobox::edit_enum;
pub use float_drag::edit_f32_zero_to_inf;
pub use float_drag::{edit_f32_zero_to_inf, edit_f32_zero_to_inf_raw};
pub use singleline_string::edit_singleline_string;
13 changes: 9 additions & 4 deletions crates/re_edit_ui/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ mod visual_bounds2d;
use datatype_editors::edit_enum;
use re_types::{
blueprint::components::{BackgroundKind, Corner2D, LockRangeDuringZoom, Visible},
components::{Color, MarkerSize, Name, Radius, StrokeWidth, Text},
components::{
AxisLength, Color, ImagePlaneDistance, MarkerSize, Name, Radius, StrokeWidth, Text,
},
};
use re_viewer_context::ViewerContext;

Expand Down Expand Up @@ -42,15 +44,18 @@ pub fn register_editors(registry: &mut re_viewer_context::ComponentUiRegistry) {
registry.add_singleline_editor_ui(marker_shape::edit_marker_shape_ui);
registry.add_singleline_editor_ui(range1d::edit_range1d);

registry.add_singleline_editor_ui::<ImagePlaneDistance>(datatype_editors::edit_f32_zero_to_inf);
registry.add_singleline_editor_ui::<AxisLength>(datatype_editors::edit_f32_zero_to_inf);

registry.add_singleline_editor_ui::<Visible>(datatype_editors::edit_bool_raw);
registry.add_singleline_editor_ui::<LockRangeDuringZoom>(datatype_editors::edit_bool);

registry.add_singleline_editor_ui::<Text>(datatype_editors::edit_singleline_string);
registry.add_singleline_editor_ui::<Name>(datatype_editors::edit_singleline_string);

registry.add_singleline_editor_ui::<Radius>(datatype_editors::edit_f32_zero_to_inf);
registry.add_singleline_editor_ui::<MarkerSize>(datatype_editors::edit_f32_zero_to_inf);
registry.add_singleline_editor_ui::<StrokeWidth>(datatype_editors::edit_f32_zero_to_inf);
registry.add_singleline_editor_ui::<Radius>(datatype_editors::edit_f32_zero_to_inf_raw);
registry.add_singleline_editor_ui::<MarkerSize>(datatype_editors::edit_f32_zero_to_inf_raw);
registry.add_singleline_editor_ui::<StrokeWidth>(datatype_editors::edit_f32_zero_to_inf_raw);

registry.add_singleline_editor_ui(|_ctx, ui, value| {
edit_enum(ui, "corner2d", value, &Corner2D::ALL)
Expand Down
29 changes: 0 additions & 29 deletions crates/re_entity_db/src/entity_properties.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,17 +114,6 @@ pub struct EntityProperties {
/// Used to scale the radii of the points in the resulting point cloud.
pub backproject_radius_scale: EditableAutoValue<f32>, // TODO(andreas): should be a component on the DepthImage archetype.

/// Whether to show the 3D transform visualization at all.
// TODO(andreas): should go away once we can disable visualizer. Revisit how to collectively enable/disable these on an entire view.
// To consider: Make a TransformAxis archetype whose indicator is what enables the visualizer
// -> size etc. are now part of this archetype, not the `Transform` archetype
// -> `TransformAxis` itself doesn't have a required component, but the visualizer has. Just like in SeriesLines & Scalar.
// TODO(andreas)/TODO(jleibs): There's a pattern here that we should capture & formalize in the API / codegen / definitions.
pub transform_3d_visible: EditableAutoValue<bool>,

/// The length of the arrows in the entity's own coordinate system (space).
pub transform_3d_size: EditableAutoValue<f32>, // TODO(andreas): should be a component on the Transform3D/TransformAxis archetype.

/// Should the legend be shown (for plot space views).
pub show_legend: EditableAutoValue<bool>, // TODO(andreas): BarChart is still using it, we already have the legend archteype!

Expand All @@ -147,8 +136,6 @@ impl Default for EntityProperties {
backproject_depth: EditableAutoValue::Auto(true),
depth_from_world_scale: EditableAutoValue::Auto(1.0),
backproject_radius_scale: EditableAutoValue::Auto(1.0),
transform_3d_visible: EditableAutoValue::Auto(false),
transform_3d_size: EditableAutoValue::Auto(1.0),
show_legend: EditableAutoValue::Auto(true),
legend_location: None,
time_series_aggregator: EditableAutoValue::Auto(TimeSeriesAggregator::default()),
Expand All @@ -175,12 +162,6 @@ impl EntityProperties {
.or(&child.backproject_radius_scale)
.clone(),

transform_3d_visible: self
.transform_3d_visible
.or(&child.transform_3d_visible)
.clone(),
transform_3d_size: self.transform_3d_size.or(&child.transform_3d_size).clone(),

show_legend: self.show_legend.or(&child.show_legend).clone(),
legend_location: self.legend_location.or(child.legend_location),
time_series_aggregator: self
Expand Down Expand Up @@ -213,12 +194,6 @@ impl EntityProperties {
.or(&self.backproject_radius_scale)
.clone(),

transform_3d_visible: other
.transform_3d_visible
.or(&self.transform_3d_visible)
.clone(),
transform_3d_size: self.transform_3d_size.or(&other.transform_3d_size).clone(),

show_legend: other.show_legend.or(&self.show_legend).clone(),
legend_location: other.legend_location.or(self.legend_location),
time_series_aggregator: other
Expand All @@ -236,8 +211,6 @@ impl EntityProperties {
backproject_depth,
depth_from_world_scale,
backproject_radius_scale,
transform_3d_visible,
transform_3d_size,
show_legend,
legend_location,
time_series_aggregator,
Expand All @@ -248,8 +221,6 @@ impl EntityProperties {
|| backproject_depth.has_edits(&other.backproject_depth)
|| depth_from_world_scale.has_edits(&other.depth_from_world_scale)
|| backproject_radius_scale.has_edits(&other.backproject_radius_scale)
|| transform_3d_visible.has_edits(&other.transform_3d_visible)
|| transform_3d_size.has_edits(&other.transform_3d_size)
|| show_legend.has_edits(&other.show_legend)
|| *legend_location != other.legend_location
|| time_series_aggregator.has_edits(&other.time_series_aggregator)
Expand Down
78 changes: 36 additions & 42 deletions crates/re_selection_panel/src/override_ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,14 @@ use re_log_types::{DataCell, DataRow, RowId, StoreKind};
use re_types_core::{components::VisualizerOverrides, ComponentName};
use re_ui::{ContextExt as _, UiExt as _};
use re_viewer_context::{
ComponentUiTypes, DataResult, OverridePath, QueryContext, SpaceViewClassExt as _,
SystemCommand, SystemCommandSender as _, ViewSystemIdentifier, ViewerContext,
ComponentUiTypes, DataResult, OverridePath, SpaceViewClassExt as _, SystemCommand,
SystemCommandSender as _, ViewContext, ViewSystemIdentifier, ViewerContext,
};
use re_viewport_blueprint::SpaceViewBlueprint;

pub fn override_ui(
ctx: &ViewerContext<'_>,
ctx: &ViewContext<'_>,
space_view: &SpaceViewBlueprint,
view_state: &dyn re_viewer_context::SpaceViewState,
instance_path: &InstancePath,
ui: &mut egui::Ui,
) {
Expand Down Expand Up @@ -47,10 +46,6 @@ pub fn override_ui(
.map(|props| props.resolved_component_overrides.keys().copied().collect())
.unwrap_or_default();

let view_systems = ctx
.space_view_class_registry
.new_visualizer_collection(space_view.class_identifier());

let mut component_to_vis: BTreeMap<ComponentName, ViewSystemIdentifier> = Default::default();

// Accumulate the components across all visualizers and track which visualizer
Expand All @@ -60,7 +55,8 @@ pub fn override_ui(
// TODO(jleibs): We can do something fancier in the future such as presenting both
// options once we have a motivating use-case.
for vis in &data_result.visualizers {
let Some(queried) = view_systems
let Some(queried) = ctx
.visualizer_collection
.get_by_identifier(*vis)
.ok()
.map(|vis| vis.visualizer_query_info().queried)
Expand All @@ -78,14 +74,14 @@ pub fn override_ui(
&query,
ctx.recording(),
ui,
&view_systems,
&component_to_vis,
&active_overrides,
&data_result,
view_state,
);

let Some(overrides) = data_result.property_overrides else {
// TODO(jleibs): This clone is annoying, but required because QueryContext wants
// a reference to the EntityPath. We could probably refactor this to avoid the clone.
let Some(overrides) = data_result.property_overrides.clone() else {
return;
};

Expand All @@ -94,6 +90,8 @@ pub fn override_ui(
.into_iter()
.sorted_by_key(|(c, _)| *c);

let query_context = ctx.query_context(&data_result, &query);

re_ui::list_item::list_item_scope(ui, "overrides", |ui| {
ui.spacing_mut().item_spacing.y = 0.0;
for (
Expand All @@ -107,7 +105,10 @@ pub fn override_ui(
let Some(visualizer_identifier) = component_to_vis.get(component_name) else {
continue;
};
let Ok(visualizer) = view_systems.get_by_identifier(*visualizer_identifier) else {
let Ok(visualizer) = ctx
.visualizer_collection
.get_by_identifier(*visualizer_identifier)
else {
re_log::warn!(
"Failed to resolve visualizer identifier {visualizer_identifier}, to a visualizer implementation"
);
Expand All @@ -117,7 +118,7 @@ pub fn override_ui(
let value_fn = |ui: &mut egui::Ui| {
let (origin_db, query) = match store_kind {
StoreKind::Blueprint => {
(ctx.store_context.blueprint, ctx.blueprint_query.clone())
(ctx.blueprint_db(), ctx.viewer_ctx.blueprint_query.clone())
}
StoreKind::Recording => (ctx.recording(), ctx.current_query()),
};
Expand All @@ -134,14 +135,8 @@ pub fn override_ui(
.cloned(); /* arc */

if let Some(results) = component_data {
ctx.component_ui_registry.singleline_edit_ui(
&QueryContext {
viewer_ctx: ctx,
target_entity_path: &instance_path.entity_path,
archetype_name: None,
query: &query,
view_state,
},
ctx.viewer_ctx.component_ui_registry.singleline_edit_ui(
&query_context,
ui,
origin_db,
entity_path_overridden,
Expand Down Expand Up @@ -177,15 +172,13 @@ pub fn override_ui(

#[allow(clippy::too_many_arguments)]
pub fn add_new_override(
ctx: &ViewerContext<'_>,
ctx: &ViewContext<'_>,
query: &LatestAtQuery,
db: &EntityDb,
ui: &mut egui::Ui,
view_systems: &re_viewer_context::VisualizerCollection,
component_to_vis: &BTreeMap<ComponentName, ViewSystemIdentifier>,
active_overrides: &BTreeSet<ComponentName>,
data_result: &DataResult,
view_state: &dyn re_viewer_context::SpaceViewState,
) {
let remaining_components = component_to_vis
.keys()
Expand All @@ -201,13 +194,7 @@ pub fn add_new_override(
opened = true;
ui.style_mut().wrap_mode = Some(egui::TextWrapMode::Extend);

let query_context = QueryContext {
viewer_ctx: ctx,
target_entity_path: &data_result.entity_path,
archetype_name: None,
query,
view_state,
};
let query_context = ctx.query_context(data_result, query);

// Present the option to add new components for each component that doesn't
// already have an active override.
Expand All @@ -227,6 +214,7 @@ pub fn add_new_override(
// If there is no registered editor, don't let the user create an override
// TODO(andreas): Can only handle single line editors right now.
if !ctx
.viewer_ctx
.component_ui_registry
.registered_ui_types(*component)
.contains(ComponentUiTypes::SingleLineEditor)
Expand All @@ -247,11 +235,16 @@ pub fn add_new_override(
.latest_at(query, &data_result.entity_path, *component, &components)
.and_then(|result| result.2[0].clone())
.or_else(|| {
view_systems.get_by_identifier(*viz).ok().and_then(|sys| {
sys.fallback_for(&query_context, *component)
.map(|fallback| DataCell::from_arrow(*component, fallback))
.ok()
})
ctx.visualizer_collection
.get_by_identifier(*viz)
.ok()
.and_then(|sys| {
sys.fallback_for(&query_context, *component)
.map(|fallback| {
DataCell::from_arrow(*component, fallback)
})
.ok()
})
})
else {
re_log::warn!("Could not identify an initial value for: {}", component);
Expand All @@ -262,16 +255,17 @@ pub fn add_new_override(

match DataRow::from_cells(
RowId::new(),
ctx.store_context.blueprint_timepoint_for_writes(),
ctx.blueprint_timepoint_for_writes(),
override_path.clone(),
[initial_data],
) {
Ok(row) => {
ctx.command_sender
.send_system(SystemCommand::UpdateBlueprint(
ctx.store_context.blueprint.store_id().clone(),
ctx.viewer_ctx.command_sender.send_system(
SystemCommand::UpdateBlueprint(
ctx.blueprint_db().store_id().clone(),
vec![row],
));
),
);
}
Err(err) => {
re_log::warn!(
Expand Down
Loading

0 comments on commit 5a10357

Please sign in to comment.