Skip to content

Commit

Permalink
Change background of 2D space views from code and/or UI (#6116)
Browse files Browse the repository at this point in the history
### What
* closes #6113

Very similar to 3D space views, even using the same gradient by default.
Usage:

```py
rrb.Spatial2DView(origin="/foo", background=[32, 0, 16])
```

The default background color is still BLACK.

---

Here the dark gradient is used.
It looks a little bit too much like the 3D space view.
<img width="916" alt="Screenshot 2024-04-25 at 18 12 05"
src="https://github.com/rerun-io/rerun/assets/1148717/46ee32d8-7234-43d7-b867-c037ad011865">

### 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/6116?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/6116?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/6116)
- [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`.

---------

Co-authored-by: Andreas Reich <[email protected]>
  • Loading branch information
emilk and Wumpf authored Apr 26, 2024
1 parent 2b4c22e commit c203d4e
Show file tree
Hide file tree
Showing 46 changed files with 463 additions and 388 deletions.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion crates/re_query_cache2/src/latest_at/to_archetype/mod.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion crates/re_space_view/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub use space_view::SpaceViewBlueprint;
pub use space_view_contents::SpaceViewContents;
pub use sub_archetypes::{
entity_path_for_space_view_sub_archetype, query_space_view_sub_archetype,
query_space_view_sub_archetype_or_default,
query_space_view_sub_archetype_or_default, space_view_sub_archetype,
};
pub use visual_time_range::{
query_visual_history, time_range_boundary_to_visible_history_boundary,
Expand Down
17 changes: 17 additions & 0 deletions crates/re_space_view/src/sub_archetypes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,23 @@ pub fn entity_path_for_space_view_sub_archetype<T: Archetype>(
space_view_blueprint_path.join(&EntityPath::from_single_string(T::name().short_name()))
}

/// Return the archetype value for the given space view, or `None` if it doesn't exist.
pub fn space_view_sub_archetype<A: re_types::Archetype>(
ctx: &re_viewer_context::ViewerContext<'_>,
space_view_id: re_viewer_context::SpaceViewId,
) -> Option<A>
where
CachedLatestAtResults: ToArchetype<A>,
{
let blueprint_db = ctx.store_context.blueprint;
let blueprint_query = ctx.blueprint_query;
let path = entity_path_for_space_view_sub_archetype::<A>(space_view_id, blueprint_db.tree());
blueprint_db
.latest_at_archetype(&path, blueprint_query)
.ok()
.flatten()
}

/// Returns `Ok(None)` if any of the required components are missing.
pub fn query_space_view_sub_archetype<A: Archetype>(
space_view_id: SpaceViewId,
Expand Down
44 changes: 44 additions & 0 deletions crates/re_space_view_spatial/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ mod ui_2d;
mod ui_3d;
mod visualizers;

use re_types::blueprint::archetypes::Background;
use re_types::components::{Resolution, TensorData};

pub use space_view_2d::SpatialSpaceView2D;
pub use space_view_3d::SpatialSpaceView3D;

Expand Down Expand Up @@ -75,3 +77,45 @@ fn query_pinhole(
.map(|c| c.value),
})
}

pub(crate) fn configure_background(
ctx: &re_viewer_context::ViewerContext<'_>,
background: re_types::blueprint::archetypes::Background,
) -> (Option<re_renderer::QueueableDrawData>, re_renderer::Rgba) {
use re_renderer::renderer;
use re_types::blueprint::components::BackgroundKind;

let Background { kind, color } = background;

match kind {
BackgroundKind::GradientDark => (
Some(
renderer::GenericSkyboxDrawData::new(
ctx.render_ctx,
renderer::GenericSkyboxType::GradientDark,
)
.into(),
),
re_renderer::Rgba::TRANSPARENT, // All zero is slightly faster to clear usually.
),

BackgroundKind::GradientBright => (
Some(
renderer::GenericSkyboxDrawData::new(
ctx.render_ctx,
renderer::GenericSkyboxType::GradientBright,
)
.into(),
),
re_renderer::Rgba::TRANSPARENT, // All zero is slightly faster to clear usually.
),

BackgroundKind::SolidColor => (
None,
// If the user has told us to use a solid color, but hasn't picked a specific color,
// we need to fall back to something. For dark mode, black makes sense.
// TODO(#3058): support light mode
color.unwrap_or(re_types::components::Color::BLACK).into(),
),
}
}
8 changes: 6 additions & 2 deletions crates/re_space_view_spatial/src/space_view_2d.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use re_format::format_f32;
use re_log_types::EntityPath;
use re_types::{
archetypes::{DepthImage, Image},
blueprint::archetypes::Background,
Archetype, ComponentName,
};
use re_viewer_context::{
Expand Down Expand Up @@ -240,14 +241,17 @@ impl SpaceViewClass for SpatialSpaceView2D {
ui: &mut egui::Ui,
state: &mut dyn SpaceViewState,
_space_origin: &EntityPath,
_space_view_id: SpaceViewId,
space_view_id: SpaceViewId,
_root_entity_properties: &mut EntityProperties,
) -> Result<(), SpaceViewSystemExecutionError> {
let state = state.downcast_mut::<SpatialSpaceViewState>()?;
ctx.re_ui
.selection_grid(ui, "spatial_settings_ui")
.show(ui, |ui| {
state.default_size_ui(ctx, ui);
state.default_sizes_ui(ctx, ui);

crate::ui::background_ui(ctx, ui, space_view_id, Background::DEFAULT_2D);

state.bounding_box_ui(ctx, ui, SpatialSpaceViewKind::TwoD);

{
Expand Down
82 changes: 9 additions & 73 deletions crates/re_space_view_spatial/src/space_view_3d.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
use itertools::Itertools;
use nohash_hasher::IntSet;

use re_entity_db::{EntityDb, EntityProperties};
use re_log_types::EntityPath;
use re_space_view::query_space_view_sub_archetype;
use re_types::{
blueprint::{archetypes::Background3D, components::Background3DKind},
components::ViewCoordinates,
Loggable,
};
use re_types::{components::ViewCoordinates, Loggable};
use re_viewer_context::{
PerSystemEntities, RecommendedSpaceView, SpaceViewClass, SpaceViewClassIdentifier,
SpaceViewClassRegistryError, SpaceViewId, SpaceViewSpawnHeuristics, SpaceViewState,
Expand Down Expand Up @@ -314,7 +310,7 @@ impl SpaceViewClass for SpatialSpaceView3D {
ctx.re_ui
.selection_grid(ui, "spatial_settings_ui")
.show(ui, |ui| {
state.default_size_ui(ctx, ui);
state.default_sizes_ui(ctx, ui);

ctx.re_ui
.grid_left_hand_label(ui, "Camera")
Expand Down Expand Up @@ -367,11 +363,14 @@ impl SpaceViewClass for SpatialSpaceView3D {
});
ui.end_row();

background_ui(ctx, space_view_id, ui);
ui.end_row();
crate::ui::background_ui(
ctx,
ui,
space_view_id,
re_types::blueprint::archetypes::Background::DEFAULT_3D,
);

state.bounding_box_ui(ctx, ui, SpatialSpaceViewKind::ThreeD);
ui.end_row();
});

Ok(())
Expand Down Expand Up @@ -400,66 +399,3 @@ impl SpaceViewClass for SpatialSpaceView3D {
crate::ui_3d::view_3d(ctx, ui, state, query, system_output)
}
}

fn background_ui(ctx: &ViewerContext<'_>, space_view_id: SpaceViewId, ui: &mut egui::Ui) {
let blueprint_db = ctx.store_context.blueprint;
let blueprint_query = ctx.blueprint_query;
let (archetype, blueprint_path) =
query_space_view_sub_archetype(space_view_id, blueprint_db, blueprint_query);

let Background3D { color, mut kind } = archetype.ok().flatten().unwrap_or_default();

ctx.re_ui.grid_left_hand_label(ui, "Background");

ui.vertical(|ui| {
let kind_before = kind;
egui::ComboBox::from_id_source("background")
.selected_text(background_color_text(kind))
.show_ui(ui, |ui| {
ui.selectable_value(
&mut kind,
Background3DKind::GradientDark,
background_color_text(Background3DKind::GradientDark),
);
ui.selectable_value(
&mut kind,
Background3DKind::GradientBright,
background_color_text(Background3DKind::GradientBright),
);
ui.selectable_value(
&mut kind,
Background3DKind::SolidColor,
background_color_text(Background3DKind::SolidColor),
);
});
if kind_before != kind {
ctx.save_blueprint_component(&blueprint_path, &kind);
}

if kind == Background3DKind::SolidColor {
let current_color = color.unwrap_or(Background3D::DEFAULT_COLOR).into();
let mut edit_color = current_color;
egui::color_picker::color_edit_button_srgba(
ui,
&mut edit_color,
egui::color_picker::Alpha::Opaque,
);
if edit_color != current_color {
ctx.save_blueprint_component(
&blueprint_path,
&re_types::components::Color::from(edit_color),
);
}
}
});

ui.end_row();
}

fn background_color_text(kind: Background3DKind) -> &'static str {
match kind {
Background3DKind::GradientDark => "Dark gradient",
Background3DKind::GradientBright => "Bright gradient",
Background3DKind::SolidColor => "Solid color",
}
}
84 changes: 79 additions & 5 deletions crates/re_space_view_spatial/src/ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,17 @@ use re_data_ui::{show_zoomed_image_region, show_zoomed_image_region_area_outline
use re_format::format_f32;
use re_renderer::OutlineConfig;
use re_space_view::ScreenshotMode;
use re_types::components::{DepthMeter, InstanceKey, TensorData, ViewCoordinates};
use re_types::tensor_data::TensorDataMeaning;
use re_types::{
blueprint::archetypes::Background,
components::{Color, DepthMeter, InstanceKey, TensorData, ViewCoordinates},
};
use re_types::{blueprint::components::BackgroundKind, tensor_data::TensorDataMeaning};
use re_viewer_context::{
HoverHighlight, Item, ItemSpaceContext, SelectionHighlight, SpaceViewHighlights,
HoverHighlight, Item, ItemSpaceContext, SelectionHighlight, SpaceViewHighlights, SpaceViewId,
SpaceViewState, SpaceViewSystemExecutionError, TensorDecodeCache, TensorStatsCache,
UiVerbosity, ViewContextCollection, ViewQuery, ViewerContext, VisualizerCollection,
};

use super::{eye::Eye, ui_2d::View2DState, ui_3d::View3DState};
use crate::scene_bounding_boxes::SceneBoundingBoxes;
use crate::{
contexts::AnnotationSceneContext,
Expand All @@ -24,6 +26,8 @@ use crate::{
};
use crate::{eye::EyeMode, heuristics::auto_size_world_heuristic};

use super::{eye::Eye, ui_2d::View2DState, ui_3d::View3DState};

/// Default auto point radius in UI points.
const AUTO_POINT_RADIUS: f32 = 1.5;

Expand Down Expand Up @@ -108,7 +112,8 @@ impl SpatialSpaceViewState {
ui.end_row();
}

pub fn default_size_ui(&mut self, ctx: &ViewerContext<'_>, ui: &mut egui::Ui) {
/// Default sizes of points and lines.
pub fn default_sizes_ui(&mut self, ctx: &ViewerContext<'_>, ui: &mut egui::Ui) {
let auto_size_world =
auto_size_world_heuristic(&self.bounding_boxes.accumulated, self.scene_num_primitives);

Expand Down Expand Up @@ -766,3 +771,72 @@ pub fn format_vector(v: glam::Vec3) -> String {
format!("[{:.02}, {:.02}, {:.02}]", v.x, v.y, v.z)
}
}

pub fn background_ui(
ctx: &ViewerContext<'_>,
ui: &mut egui::Ui,
space_view_id: SpaceViewId,
default_background: Background,
) {
let blueprint_db = ctx.store_context.blueprint;
let blueprint_query = ctx.blueprint_query;
let (archetype, blueprint_path) =
re_space_view::query_space_view_sub_archetype(space_view_id, blueprint_db, blueprint_query);

let Background { color, mut kind } = archetype.ok().flatten().unwrap_or(default_background);

ctx.re_ui.grid_left_hand_label(ui, "Background");

ui.vertical(|ui| {
let kind_before = kind;
egui::ComboBox::from_id_source("background")
.selected_text(background_color_text(kind))
.show_ui(ui, |ui| {
ui.selectable_value(
&mut kind,
BackgroundKind::GradientDark,
background_color_text(BackgroundKind::GradientDark),
);
ui.selectable_value(
&mut kind,
BackgroundKind::GradientBright,
background_color_text(BackgroundKind::GradientBright),
);
ui.selectable_value(
&mut kind,
BackgroundKind::SolidColor,
background_color_text(BackgroundKind::SolidColor),
);
});
if kind_before != kind {
ctx.save_blueprint_component(&blueprint_path, &kind);
}

if kind == BackgroundKind::SolidColor {
let current_color = color
.or(default_background.color)
.unwrap_or(Color::BLACK)
.into();
let mut edit_color = current_color;
egui::color_picker::color_edit_button_srgba(
ui,
&mut edit_color,
egui::color_picker::Alpha::Opaque,
);
if edit_color != current_color {
ctx.save_blueprint_component(&blueprint_path, &BackgroundKind::SolidColor);
ctx.save_blueprint_component(&blueprint_path, &Color::from(edit_color));
}
}
});

ui.end_row();
}

fn background_color_text(kind: BackgroundKind) -> &'static str {
match kind {
BackgroundKind::GradientDark => "Dark gradient",
BackgroundKind::GradientBright => "Bright gradient",
BackgroundKind::SolidColor => "Solid color",
}
}
Loading

0 comments on commit c203d4e

Please sign in to comment.