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

Fix draw_order not working #5794

Merged
merged 6 commits into from
Apr 4, 2024
Merged
Show file tree
Hide file tree
Changes from 3 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
8 changes: 7 additions & 1 deletion crates/re_space_view_spatial/src/contexts/depth_offsets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,13 @@ impl ViewContextSystem for EntityDepthOffsets {

// Use a BTreeSet for entity hashes to get a stable order.
let mut entities_per_draw_order = BTreeMap::<DrawOrder, BTreeSet<DrawOrderTarget>>::new();
for data_result in query.iter_visible_data_results(ctx, Self::identifier()) {
for data_result in query.iter_all_data_results() {
// Note that we can't use `query.iter_visible_data_results` here since `EntityDepthOffsets` isn't a visualizer
// and thus not in the list of per system data results.
if !data_result.is_visible(ctx) {
continue;
}

if let Some(draw_order) = store
.query_latest_component::<DrawOrder>(&data_result.entity_path, &ctx.current_query())
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ impl ViewContextSystem for TransformContext {
// Build an entity_property_map for just the CamerasParts, where we would expect to find
// the image_depth_plane_distance property.
let entity_prop_map: EntityPropertyMap = query
.per_system_data_results
.per_visualizer_data_results
.get(&CamerasVisualizer::identifier())
.map(|results| {
results
Expand Down
12 changes: 6 additions & 6 deletions crates/re_viewer_context/src/space_view/view_query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -401,10 +401,10 @@ pub struct ViewQuery<'s> {
/// The root of the space in which context the query happens.
pub space_origin: &'s EntityPath,

/// All queried [`DataResult`]s.
/// All [`DataResult`]s that are queried by active visualizers.
///
/// Contains also invisible objects, use `iter_entities` to iterate over visible ones.
pub per_system_data_results: PerSystemDataResults<'s>,
/// Contains also invisible objects, use `iter_visible_data_results` to iterate over visible ones.
pub per_visualizer_data_results: PerSystemDataResults<'s>,

/// The timeline we're on.
pub timeline: Timeline,
Expand All @@ -423,12 +423,12 @@ impl<'s> ViewQuery<'s> {
pub fn iter_visible_data_results<'a>(
&'a self,
ctx: &'a ViewerContext<'a>,
system: ViewSystemIdentifier,
visualizer: ViewSystemIdentifier,
) -> impl Iterator<Item = &DataResult>
where
's: 'a,
{
self.per_system_data_results.get(&system).map_or(
self.per_visualizer_data_results.get(&visualizer).map_or(
itertools::Either::Left(std::iter::empty()),
|results| {
itertools::Either::Right(
Expand All @@ -443,7 +443,7 @@ impl<'s> ViewQuery<'s> {

/// Iterates over all [`DataResult`]s of the [`ViewQuery`].
pub fn iter_all_data_results(&self) -> impl Iterator<Item = &DataResult> + '_ {
self.per_system_data_results
self.per_visualizer_data_results
.values()
.flat_map(|data_results| data_results.iter().copied())
}
Expand Down
6 changes: 3 additions & 3 deletions crates/re_viewport/src/system_execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,13 +104,13 @@ pub fn execute_systems_for_space_view<'a>(

let query_result = ctx.lookup_query_result(space_view.id);

let mut per_system_data_results = PerSystemDataResults::default();
let mut per_visualizer_data_results = PerSystemDataResults::default();
{
re_tracing::profile_scope!("per_system_data_results");

query_result.tree.visit(&mut |node| {
for system in &node.data_result.visualizers {
per_system_data_results
per_visualizer_data_results
.entry(*system)
.or_default()
.push(&node.data_result);
Expand All @@ -122,7 +122,7 @@ pub fn execute_systems_for_space_view<'a>(
let query = re_viewer_context::ViewQuery {
space_view_id: space_view.id,
space_origin: &space_view.space_origin,
per_system_data_results,
per_visualizer_data_results,
timeline: *ctx.rec_cfg.time_ctrl.read().timeline(),
latest_at,
highlights,
Expand Down
96 changes: 96 additions & 0 deletions tests/python/release_checklist/check_draw_order.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
from __future__ import annotations

import os
from argparse import Namespace
from uuid import uuid4

import numpy as np
import rerun as rr
import rerun.blueprint as rrb

README = """
# 2D Draw order

This checks whether the heuristics do the right thing with mixed 2D and 3D data.
Wumpf marked this conversation as resolved.
Show resolved Hide resolved

Reset the blueprint to make sure you are viewing new heuristics and not a cached blueprint.

### Action
You should see a single 2D space view with the following features:
- Gray background image
- On top of the background a green/red gradient image
- On top of that a blue (slightly transparent) blue square
- On top of the blue square a white square. *Nothing* is overlapping the white square!
- Between the gradient and the blue square rectangle (Box2D)
- Lines *behind* the rectangle
- Regular raster of points *in front* of the rectangle (unbroken by the rectangle)
"""


def log_readme() -> None:
rr.log("readme", rr.TextDocument(README, media_type=rr.MediaType.MARKDOWN), timeless=True)


def run_2d_layering() -> None:
rr.set_time_seconds("sim_time", 1)

# Large gray background.
img = np.full((512, 512), 64, dtype="uint8")
rr.log("2d_layering/background", rr.Image(img, draw_order=0.0))

# Smaller gradient in the middle.
img = np.zeros((256, 256, 3), dtype="uint8")
img[:, :, 0] = np.linspace(0, 255, 256, dtype="uint8")
img[:, :, 1] = np.linspace(0, 255, 256, dtype="uint8")
img[:, :, 1] = img[:, :, 1].transpose()
rr.log("2d_layering/middle_gradient", rr.Image(img, draw_order=1.0))

# Slightly smaller blue in the middle, on the same layer as the previous.
img = np.full((192, 192, 3), (0, 0, 255), dtype="uint8")
rr.log("2d_layering/middle_blue", rr.Image(img, draw_order=1.0))

# Small white on top.
img = np.full((128, 128), 255, dtype="uint8")
rr.log("2d_layering/top", rr.Image(img, draw_order=2.0))

# Rectangle in between the top and the middle.
rr.log(
"2d_layering/rect_between_top_and_middle",
rr.Boxes2D(array=[64, 64, 256, 256], draw_order=1.5, array_format=rr.Box2DFormat.XYWH),
)

# Lines behind the rectangle.
rr.log(
"2d_layering/lines_behind_rect",
rr.LineStrips2D([(i * 20, i % 2 * 100 + 100) for i in range(20)], draw_order=1.25),
)

# And some points in front of the rectangle.
rr.log(
"2d_layering/points_between_top_and_middle",
rr.Points2D(
[(32.0 + int(i / 16) * 16.0, 64.0 + (i % 16) * 16.0) for i in range(16 * 16)],
draw_order=1.51,
),
)


def run(args: Namespace) -> None:
rr.script_setup(
args,
f"{os.path.basename(__file__)}",
recording_id=uuid4(),
default_blueprint=rrb.Grid(rrb.Spatial2DView(origin="/"), rrb.TextDocumentView(origin="readme")),
)

log_readme()
run_2d_layering()


if __name__ == "__main__":
import argparse

parser = argparse.ArgumentParser(description="Interactive release checklist")
rr.script_add_args(parser)
args = parser.parse_args()
run(args)
45 changes: 0 additions & 45 deletions tests/python/test_api/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,50 +97,6 @@ def small_image() -> None:
rr.log("small_image", rr.Image(img))


def run_2d_layering() -> None:
rr.set_time_seconds("sim_time", 1)

# Large gray background.
img = np.full((512, 512), 64, dtype="uint8")
rr.log("2d_layering/background", rr.Image(img, draw_order=0.0))

# Smaller gradient in the middle.
img = np.zeros((256, 256, 3), dtype="uint8")
img[:, :, 0] = np.linspace(0, 255, 256, dtype="uint8")
img[:, :, 1] = np.linspace(0, 255, 256, dtype="uint8")
img[:, :, 1] = img[:, :, 1].transpose()
rr.log("2d_layering/middle_gradient", rr.Image(img, draw_order=1.0))

# Slightly smaller blue in the middle, on the same layer as the previous.
img = np.full((192, 192, 3), (0, 0, 255), dtype="uint8")
rr.log("2d_layering/middle_blue", rr.Image(img, draw_order=1.0))

# Small white on top.
img = np.full((128, 128), 255, dtype="uint8")
rr.log("2d_layering/top", rr.Image(img, draw_order=2.0))

# Rectangle in between the top and the middle.
rr.log(
"2d_layering/rect_between_top_and_middle",
rr.Boxes2D(array=[64, 64, 256, 256], draw_order=1.5, array_format=rr.Box2DFormat.XYWH),
)

# Lines behind the rectangle.
rr.log(
"2d_layering/lines_behind_rect",
rr.LineStrips2D([(i * 20, i % 2 * 100 + 100) for i in range(20)], draw_order=1.25),
)

# And some points in front of the rectangle.
rr.log(
"2d_layering/points_between_top_and_middle",
rr.Points2D(
[(32.0 + int(i / 16) * 16.0, 64.0 + (i % 16) * 16.0) for i in range(16 * 16)],
draw_order=1.51,
),
)


def transforms() -> None:
rr.log("transforms", rr.ViewCoordinates.RIGHT_HAND_Y_UP, timeless=True)

Expand Down Expand Up @@ -474,7 +430,6 @@ def spawn_test(test: Callable[[], None], rec: rr.RecordingStream) -> None:

def main() -> None:
tests = {
"2d_layering": run_2d_layering,
"2d_lines": run_2d_lines,
"3d_points": run_3d_points,
"bbox": run_bounding_box,
Expand Down
65 changes: 0 additions & 65 deletions tests/rust/test_api/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,67 +215,6 @@ fn colored_tensor<F: Fn(usize, usize) -> [u8; 3]>(
.unwrap()
}

fn test_2d_layering(rec: &RecordingStream) -> anyhow::Result<()> {
use ndarray::prelude::*;

use rerun::archetypes::{Boxes2D, Image, LineStrips2D, Points2D};

rec.set_time_seconds("sim_time", 1f64);

// Add several overlapping images.
// Large dark gray in the background
let img = Array::<u8, _>::from_elem((512, 512, 1).f(), 64)
.as_standard_layout()
.view()
.to_owned();
rec.log(
"2d_layering/background",
&Image::try_from(img)?.with_draw_order(0.0),
)?;
// Smaller gradient in the middle
let img = colored_tensor(256, 256, |x, y| [x as u8, y as u8, 0]);
rec.log(
"2d_layering/middle_gradient",
&Image::try_from(img)?.with_draw_order(1.0),
)?;
// Slightly smaller blue in the middle, on the same layer as the previous.
let img = colored_tensor(192, 192, |_, _| [0, 0, 255]);
rec.log(
"2d_layering/middle_blue",
&Image::try_from(img)?.with_draw_order(1.0),
)?;
// Small white on top.
let img = Array::<u8, _>::from_elem((128, 128, 1).f(), 255);
rec.log(
"2d_layering/top",
&Image::try_from(img)?.with_draw_order(2.0),
)?;

// Rectangle in between the top and the middle.
rec.log(
"2d_layering/rect_between_top_and_middle",
&Boxes2D::from_mins_and_sizes([(64.0, 64.0)], [(256.0, 256.0)]).with_draw_order(1.5),
)?;

// Lines behind the rectangle.
rec.log(
"2d_layering/lines_behind_rect",
&LineStrips2D::new([(0..20).map(|i| ((i * 20) as f32, (i % 2 * 100 + 100) as f32))])
.with_draw_order(1.25),
)?;

// And some points in front of the rectangle.
rec.log(
"2d_layering/points_between_top_and_middle",
&Points2D::new(
(0..256).map(|i| (32.0 + (i / 16) as f32 * 16.0, 64.0 + (i % 16) as f32 * 16.0)),
)
.with_draw_order(1.51),
)?;

Ok(())
}

fn test_segmentation(rec: &RecordingStream) -> anyhow::Result<()> {
use rerun::{
archetypes::{AnnotationContext, Points2D},
Expand Down Expand Up @@ -539,9 +478,6 @@ enum Demo {
#[value(name("rects"))]
Rects,

#[value(name("2d_ordering"))]
TwoDOrdering,

#[value(name("segmentation"))]
Segmentation,

Expand Down Expand Up @@ -576,7 +512,6 @@ fn run(rec: &RecordingStream, args: &Args) -> anyhow::Result<()> {
Demo::LogCleared => test_log_cleared(rec)?,
Demo::Points3D => test_3d_points(rec)?,
Demo::Rects => test_rects(rec)?,
Demo::TwoDOrdering => test_2d_layering(rec)?,
Demo::Segmentation => test_segmentation(rec)?,
Demo::TextLogs => test_text_logs(rec)?,
Demo::Transforms3D => test_transforms_3d(rec)?,
Expand Down
Loading