Skip to content

Commit 4dada3c

Browse files
authored
Split Image visualizer into Image/DepthImage/SegmentationImage (#6654)
### What * follow-up to #6644 * Fixes #6548 * Fixes #6660 Lots of copy & paste between the three visualizers left. Didn't want to remove it entirely to not make it too hard to have them diverge more in the future. But thanks to some clean-up passes it's not too bad (imho). ![image](https://github.com/rerun-io/rerun/assets/1220815/fe2b92eb-01ce-4864-b32d-7613355c763c) ![image](https://github.com/rerun-io/rerun/assets/1220815/1ed948d7-5cbf-45cd-9204-244aec4cd3f7) ![image](https://github.com/rerun-io/rerun/assets/1220815/3fe3c087-b39c-49ec-b795-6f3507059604) ### 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/6654?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/6654?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/6654) - [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`.
1 parent bdc1fd1 commit 4dada3c

File tree

18 files changed

+1095
-1004
lines changed

18 files changed

+1095
-1004
lines changed

crates/re_data_ui/src/image.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use re_viewer_context::{
1212
ViewerContext,
1313
};
1414

15-
use crate::image_meaning_for_entity;
15+
use crate::image_meaning::image_meaning_for_entity;
1616

1717
use super::EntityDataUi;
1818

crates/re_data_ui/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ pub use crate::image::{
3737
};
3838
pub use component::EntityLatestAtResults;
3939
pub use component_ui_registry::{add_to_registry, create_component_ui_registry};
40-
pub use image_meaning::image_meaning_for_entity;
4140

4241
/// Sort components for display in the UI.
4342
pub fn sorted_component_list_for_ui<'a>(

crates/re_space_view_spatial/src/lib.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ mod instance_hash_conversions;
1212
mod max_image_dimension_subscriber;
1313
mod mesh_cache;
1414
mod mesh_loader;
15+
mod pickable_image;
1516
mod picking;
1617
mod scene_bounding_boxes;
1718
mod space_camera_3d;
@@ -25,13 +26,16 @@ mod view_3d;
2526
mod view_3d_properties;
2627
mod visualizers;
2728

28-
use re_space_view::DataResultQuery as _;
29-
use re_viewer_context::{ViewContext, ViewerContext};
3029
pub use view_2d::SpatialSpaceView2D;
3130
pub use view_3d::SpatialSpaceView3D;
3231

32+
pub(crate) use pickable_image::PickableImageRect;
33+
3334
// ---
3435

36+
use re_space_view::DataResultQuery as _;
37+
use re_viewer_context::{ViewContext, ViewerContext};
38+
3539
use re_renderer::RenderContext;
3640
use re_types::blueprint::components::BackgroundKind;
3741
use re_types::components::{Color, Resolution, TensorData};
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
use re_log_types::EntityPath;
2+
use re_renderer::renderer::TexturedRect;
3+
4+
/// Image rectangle that can be picked in the view.
5+
pub struct PickableImageRect {
6+
/// Path to the image (note image instance ids would refer to pixels!)
7+
pub ent_path: EntityPath,
8+
9+
/// Textured rectangle used by the renderer.
10+
pub textured_rect: TexturedRect,
11+
}

crates/re_space_view_spatial/src/picking.rs

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
//! Handles picking in 2D and 3D spaces.
22
3-
use ahash::HashSet;
3+
use std::collections::HashSet;
4+
45
use re_entity_db::InstancePathHash;
56
use re_log_types::Instance;
67
use re_renderer::PickingLayerProcessor;
78

8-
use crate::visualizers::ViewerImage;
9+
use crate::PickableImageRect;
910
use crate::{eye::Eye, instance_hash_conversions::instance_path_hash_from_picking_layer_id};
1011

1112
#[derive(Clone, PartialEq, Eq)]
@@ -102,12 +103,12 @@ impl PickingContext {
102103
}
103104

104105
/// Performs picking for a given scene.
105-
pub fn pick(
106+
pub fn pick<'a>(
106107
&self,
107108
render_ctx: &re_renderer::RenderContext,
108109
gpu_readback_identifier: re_renderer::GpuReadbackIdentifier,
109110
previous_picking_result: &Option<PickingResult>,
110-
images: &[ViewerImage],
111+
images: impl Iterator<Item = &'a PickableImageRect>,
111112
ui_rects: &[PickableUiRect],
112113
) -> PickingResult {
113114
re_tracing::profile_function!();
@@ -240,11 +241,16 @@ fn picking_gpu(
240241
}
241242
}
242243

243-
fn picking_textured_rects(context: &PickingContext, images: &[ViewerImage]) -> Vec<PickingRayHit> {
244+
fn picking_textured_rects<'a>(
245+
context: &PickingContext,
246+
images: impl Iterator<Item = &'a PickableImageRect>,
247+
) -> Vec<PickingRayHit> {
244248
re_tracing::profile_function!();
245249

246250
let mut hits = Vec::new();
247251

252+
let mut hit_image_rect_entities = HashSet::new();
253+
248254
for image in images {
249255
let rect = &image.textured_rect;
250256
let Some(normal) = rect.extent_u.cross(rect.extent_v).try_normalize() else {
@@ -266,18 +272,24 @@ fn picking_textured_rects(context: &PickingContext, images: &[ViewerImage]) -> V
266272

267273
if (0.0..=1.0).contains(&u) && (0.0..=1.0).contains(&v) {
268274
let [width, height] = rect.colormapped_texture.width_height();
269-
hits.push(PickingRayHit {
270-
instance_path_hash: InstancePathHash {
271-
entity_path_hash: image.ent_path.hash(),
272-
instance: Instance::from_2d_image_coordinate(
273-
[(u * width as f32) as u32, (v * height as f32) as u32],
274-
width as u64,
275-
),
276-
},
277-
space_position: intersection_world,
278-
hit_type: PickingHitType::TexturedRect,
279-
depth_offset: rect.options.depth_offset,
280-
});
275+
276+
// Ignore the image if we hit the same entity already as an image.
277+
// This happens if the same entity has multiple textured rects.
278+
let entity_path_hash = image.ent_path.hash();
279+
if hit_image_rect_entities.insert(entity_path_hash) {
280+
hits.push(PickingRayHit {
281+
instance_path_hash: InstancePathHash {
282+
entity_path_hash,
283+
instance: Instance::from_2d_image_coordinate(
284+
[(u * width as f32) as u32, (v * height as f32) as u32],
285+
width as u64,
286+
),
287+
},
288+
space_position: intersection_world,
289+
hit_type: PickingHitType::TexturedRect,
290+
depth_offset: rect.options.depth_offset,
291+
});
292+
}
281293
}
282294
}
283295

crates/re_space_view_spatial/src/ui.rs

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ use egui::{epaint::util::OrderedFloat, text::TextWrapping, NumExt, WidgetText};
44
use macaw::BoundingBox;
55

66
use re_data_ui::{
7-
image_meaning_for_entity, item_ui, show_zoomed_image_region,
8-
show_zoomed_image_region_area_outline, DataUi,
7+
item_ui, show_zoomed_image_region, show_zoomed_image_region_area_outline, DataUi,
98
};
109
use re_format::format_f32;
1110
use re_log_types::Instance;
@@ -29,7 +28,10 @@ use crate::{
2928
contexts::AnnotationSceneContext,
3029
picking::{PickableUiRect, PickingContext, PickingHitType, PickingResult},
3130
view_kind::SpatialSpaceViewKind,
32-
visualizers::{CamerasVisualizer, ImageVisualizer, UiLabel, UiLabelTarget},
31+
visualizers::{
32+
CamerasVisualizer, DepthImageVisualizer, ImageVisualizer, SegmentationImageVisualizer,
33+
UiLabel, UiLabelTarget,
34+
},
3335
};
3436
use crate::{contexts::PrimitiveCounter, scene_bounding_boxes::SceneBoundingBoxes};
3537
use crate::{eye::EyeMode, heuristics::auto_size_world_heuristic};
@@ -108,13 +110,10 @@ impl SpatialSpaceViewState {
108110
.num_primitives
109111
.load(std::sync::atomic::Ordering::Relaxed);
110112

111-
self.num_non_segmentation_images_last_frame = system_output
112-
.view_systems
113-
.get::<ImageVisualizer>()?
114-
.images
115-
.iter()
116-
.filter(|i| i.meaning != TensorDataMeaning::ClassId)
117-
.count();
113+
let view_systems = &system_output.view_systems;
114+
let num_images = view_systems.get::<ImageVisualizer>()?.images.len();
115+
let num_depth_images = view_systems.get::<DepthImageVisualizer>()?.images.len();
116+
self.num_non_segmentation_images_last_frame = num_images + num_depth_images;
118117

119118
Ok(())
120119
}
@@ -499,12 +498,18 @@ pub fn picking(
499498

500499
let annotations = view_ctx.get::<AnnotationSceneContext>()?;
501500
let images = visualizers.get::<ImageVisualizer>()?;
501+
let depth_images = visualizers.get::<DepthImageVisualizer>()?;
502+
let segmentation_images = visualizers.get::<SegmentationImageVisualizer>()?;
502503

503504
let picking_result = picking_context.pick(
504505
render_ctx,
505506
query.space_view_id.gpu_readback_id(),
506507
&state.previous_picking_result,
507-
&images.images,
508+
images
509+
.images
510+
.iter()
511+
.chain(depth_images.images.iter())
512+
.chain(segmentation_images.images.iter()),
508513
ui_rects,
509514
);
510515
state.previous_picking_result = Some(picking_result.clone());
@@ -546,10 +551,8 @@ pub fn picking(
546551
continue;
547552
}
548553

549-
let store = ctx.recording_store();
550-
551554
// Special hover ui for images.
552-
let is_depth_cloud = images
555+
let is_depth_cloud = depth_images
553556
.depth_cloud_entities
554557
.contains(&instance_path.entity_path.hash());
555558

@@ -563,11 +566,22 @@ pub fn picking(
563566
}
564567

565568
let picked_image = if hit.hit_type == PickingHitType::TexturedRect || is_depth_cloud {
566-
let meaning = image_meaning_for_entity(
567-
&instance_path.entity_path,
568-
&query.latest_at_query(),
569-
store,
570-
);
569+
let meaning = if segmentation_images
570+
.images
571+
.iter()
572+
.any(|i| i.ent_path == instance_path.entity_path)
573+
{
574+
TensorDataMeaning::ClassId
575+
} else if is_depth_cloud
576+
|| depth_images
577+
.images
578+
.iter()
579+
.any(|i| i.ent_path == instance_path.entity_path)
580+
{
581+
TensorDataMeaning::Depth
582+
} else {
583+
TensorDataMeaning::Unknown
584+
};
571585

572586
let query_shadowed_defaults = false;
573587
let results = latest_at_with_blueprint_resolved_data(

0 commit comments

Comments
 (0)