Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve ui for tensors and color map selection #1683

Merged
merged 4 commits into from
Mar 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 4 additions & 9 deletions crates/re_data_store/src/entity_properties.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,6 @@ pub struct EntityProperties {
pub visible_history: ExtraQueryHistory,
pub interactive: bool,

/// Enable color mapping?
///
/// See [`Self::color_mapper`] to select an actual mapping.
pub color_mapping: bool,

/// What kind of color mapping should be applied (none, map, texture, transfer..)?
pub color_mapper: EditableAutoValue<ColorMapper>,

Expand Down Expand Up @@ -87,7 +82,6 @@ impl EntityProperties {
visible_history: self.visible_history.with_child(&child.visible_history),
interactive: self.interactive && child.interactive,

color_mapping: self.color_mapping || child.color_mapping,
color_mapper: self.color_mapper.or(&child.color_mapper).clone(),

pinhole_image_plane_distance: self
Expand Down Expand Up @@ -116,7 +110,6 @@ impl Default for EntityProperties {
visible: true,
visible_history: ExtraQueryHistory::default(),
interactive: true,
color_mapping: false,
color_mapper: EditableAutoValue::default(),
pinhole_image_plane_distance: EditableAutoValue::default(),
backproject_depth: false,
Expand Down Expand Up @@ -152,10 +145,11 @@ impl ExtraQueryHistory {
}
} // ----------------------------------------------------------------------------

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub enum ColorMap {
Grayscale,
#[default]
Turbo,
Viridis,
Plasma,
Expand Down Expand Up @@ -194,8 +188,9 @@ impl std::fmt::Display for ColorMapper {
}

impl Default for ColorMapper {
#[inline]
fn default() -> Self {
Self::ColorMap(ColorMap::Grayscale)
Self::ColorMap(ColorMap::default())
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ use arrow2_convert::{
pub struct BinaryBuffer(pub Buffer<u8>);

impl BinaryBuffer {
#[inline]
pub fn num_bytes(&self) -> usize {
self.0.len()
}

#[inline]
pub fn as_slice(&self) -> &[u8] {
self.0.as_slice()
}
Expand All @@ -26,12 +32,14 @@ impl BinaryBuffer {
impl Index<usize> for BinaryBuffer {
type Output = u8;

#[inline]
fn index(&self, i: usize) -> &u8 {
&self.0[i]
}
}

impl From<Vec<u8>> for BinaryBuffer {
#[inline]
fn from(v: Vec<u8>) -> Self {
Self(v.into())
}
Expand Down
65 changes: 56 additions & 9 deletions crates/re_viewer/src/ui/data_ui/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,14 @@ impl DataUi for Tensor {
self.dtype(),
format_tensor_shape_single_line(self.shape())
))
.on_hover_ui(|ui| tensor_dtype_and_shape_ui(ctx.re_ui, ui, self, tensor_stats));
.on_hover_ui(|ui| tensor_summary_ui(ctx.re_ui, ui, self, tensor_stats));
});
}

UiVerbosity::All | UiVerbosity::Reduced => {
ui.vertical(|ui| {
ui.set_min_width(100.0);
tensor_dtype_and_shape_ui(ctx.re_ui, ui, self, tensor_stats);
tensor_summary_ui(ctx.re_ui, ui, self, tensor_stats);

if let Some(retained_img) = tensor_view.retained_image {
let max_size = ui
Expand Down Expand Up @@ -115,12 +115,20 @@ impl DataUi for Tensor {
}
}

pub fn tensor_dtype_and_shape_ui_grid_contents(
pub fn tensor_summary_ui_grid_contents(
re_ui: &re_ui::ReUi,
ui: &mut egui::Ui,
tensor: &Tensor,
tensor_stats: Option<&TensorStats>,
) {
let Tensor {
tensor_id: _,
shape,
data,
meaning,
meter,
} = tensor;

re_ui
.grid_left_hand_label(ui, "Data type")
.on_hover_text("Data type used for all individual elements within the tensor.");
Expand All @@ -134,16 +142,55 @@ pub fn tensor_dtype_and_shape_ui_grid_contents(
// For unnamed tensor dimension more than a single line usually doesn't make sense!
// But what if some are named and some are not?
// -> If more than 1 is named, make it a column!
if tensor.shape().iter().filter(|d| d.name.is_some()).count() > 1 {
for dim in tensor.shape() {
if shape.iter().filter(|d| d.name.is_some()).count() > 1 {
for dim in shape {
ui.label(dim.to_string());
}
} else {
ui.label(format_tensor_shape_single_line(tensor.shape()));
ui.label(format_tensor_shape_single_line(shape));
}
});
ui.end_row();

if *meaning != TensorDataMeaning::Unknown {
re_ui.grid_left_hand_label(ui, "Meaning");
ui.label(match meaning {
TensorDataMeaning::Unknown => "",
TensorDataMeaning::ClassId => "Class ID",
TensorDataMeaning::Depth => "Depth",
});
ui.end_row();
}

if let Some(meter) = meter {
re_ui
.grid_left_hand_label(ui, "Meter")
.on_hover_text(format!("{meter} depth units equals one world unit"));
ui.label(meter.to_string());
ui.end_row();
}

match data {
re_log_types::component_types::TensorData::U8(_)
| re_log_types::component_types::TensorData::U16(_)
| re_log_types::component_types::TensorData::U32(_)
| re_log_types::component_types::TensorData::U64(_)
| re_log_types::component_types::TensorData::I8(_)
| re_log_types::component_types::TensorData::I16(_)
| re_log_types::component_types::TensorData::I32(_)
| re_log_types::component_types::TensorData::I64(_)
| re_log_types::component_types::TensorData::F32(_)
| re_log_types::component_types::TensorData::F64(_) => {}
re_log_types::component_types::TensorData::JPEG(jpeg_bytes) => {
re_ui.grid_left_hand_label(ui, "Encoding");
ui.label(format!(
"{} JPEG",
re_format::format_bytes(jpeg_bytes.num_bytes() as _),
));
ui.end_row();
}
}

if let Some(TensorStats {
range: Some((min, max)),
}) = tensor_stats
Expand All @@ -159,16 +206,16 @@ pub fn tensor_dtype_and_shape_ui_grid_contents(
}
}

pub fn tensor_dtype_and_shape_ui(
pub fn tensor_summary_ui(
re_ui: &re_ui::ReUi,
ui: &mut egui::Ui,
tensor: &Tensor,
tensor_stats: Option<&TensorStats>,
) {
egui::Grid::new("tensor_dtype_and_shape_ui")
egui::Grid::new("tensor_summary_ui")
.num_columns(2)
.show(ui, |ui| {
tensor_dtype_and_shape_ui_grid_contents(re_ui, ui, tensor, tensor_stats);
tensor_summary_ui_grid_contents(re_ui, ui, tensor, tensor_stats);
});
}

Expand Down
8 changes: 0 additions & 8 deletions crates/re_viewer/src/ui/selection_panel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -424,14 +424,6 @@ fn entity_props_ui(
}

fn colormap_props_ui(ui: &mut egui::Ui, entity_props: &mut EntityProperties) {
ui.checkbox(&mut entity_props.color_mapping, "Color mapping")
.on_hover_text("Toggles color mapping");
ui.end_row();

if !entity_props.color_mapping {
return;
}

let current = *entity_props.color_mapper.get();

ui.label("Color map");
Expand Down
23 changes: 10 additions & 13 deletions crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs
Original file line number Diff line number Diff line change
Expand Up @@ -307,19 +307,16 @@ impl ImagesPart {

let world_from_obj = extrinsics * glam::Mat4::from_scale(glam::Vec3::splat(scale));

let colormap = properties
.color_mapping
.then(|| match *properties.color_mapper.get() {
re_data_store::ColorMapper::ColorMap(colormap) => match colormap {
re_data_store::ColorMap::Grayscale => ColorMap::Grayscale,
re_data_store::ColorMap::Turbo => ColorMap::ColorMapTurbo,
re_data_store::ColorMap::Viridis => ColorMap::ColorMapViridis,
re_data_store::ColorMap::Plasma => ColorMap::ColorMapPlasma,
re_data_store::ColorMap::Magma => ColorMap::ColorMapMagma,
re_data_store::ColorMap::Inferno => ColorMap::ColorMapInferno,
},
})
.unwrap_or(ColorMap::Grayscale);
let colormap = match *properties.color_mapper.get() {
re_data_store::ColorMapper::ColorMap(colormap) => match colormap {
re_data_store::ColorMap::Grayscale => ColorMap::Grayscale,
re_data_store::ColorMap::Turbo => ColorMap::ColorMapTurbo,
re_data_store::ColorMap::Viridis => ColorMap::ColorMapViridis,
re_data_store::ColorMap::Plasma => ColorMap::ColorMapPlasma,
re_data_store::ColorMap::Magma => ColorMap::ColorMapMagma,
re_data_store::ColorMap::Inferno => ColorMap::ColorMapInferno,
},
};

scene.primitives.depth_clouds.push(DepthCloud {
depth_camera_extrinsics: world_from_obj,
Expand Down
4 changes: 2 additions & 2 deletions crates/re_viewer/src/ui/view_tensor/ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use re_log_types::{
};
use re_tensor_ops::dimension_mapping::{DimensionMapping, DimensionSelector};

use crate::ui::data_ui::image::tensor_dtype_and_shape_ui_grid_contents;
use crate::ui::data_ui::image::tensor_summary_ui_grid_contents;

use super::dimension_mapping_ui;

Expand Down Expand Up @@ -56,7 +56,7 @@ impl ViewTensorState {
ctx.re_ui
.selection_grid(ui, "tensor_selection_ui")
.show(ui, |ui| {
tensor_dtype_and_shape_ui_grid_contents(
tensor_summary_ui_grid_contents(
ctx.re_ui,
ui,
tensor,
Expand Down