From c739dd82d62d476e5b7c3ec2e978b2fac38129d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jochen=20G=C3=B6rtler?= Date: Wed, 11 Dec 2024 11:21:43 +0100 Subject: [PATCH] Add missing screenshots of graph view archetypes (#8371) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### Related * Closes #8277 * Closes #8327 * Closes #8237 ### What This fixes many problems around the state of the graph view. Turns out the scene rect alone is not sufficient to store all of the viewer state (who would have thought 😇). --------- Co-authored-by: Andreas Reich --- .../rerun/archetypes/graph_edges.fbs | 6 ++-- .../rerun/archetypes/graph_nodes.fbs | 6 ++-- crates/viewer/re_view_graph/src/properties.rs | 10 ++++++- crates/viewer/re_view_graph/src/ui/state.rs | 4 ++- crates/viewer/re_view_graph/src/view.rs | 26 +++++++++++++---- .../reference/types/archetypes/graph_edges.md | 16 ++++++++-- .../reference/types/archetypes/graph_nodes.md | 16 ++++++++-- examples/rust/chess_robby_fischer/README.md | 6 ++-- examples/rust/graph_lattice/README.md | 29 +++++++++++++++++-- rerun_cpp/src/rerun/blueprint.hpp | 11 ------- rerun_py/docs/gen_common_index.py | 20 ++++++------- rerun_py/rerun_sdk/rerun/blueprint/api.py | 2 +- .../tests/unit/test_container_blueprint.py | 10 +++---- rerun_py/tests/unit/test_view_contents.py | 2 +- 14 files changed, 110 insertions(+), 54 deletions(-) delete mode 100644 rerun_cpp/src/rerun/blueprint.hpp diff --git a/crates/store/re_types/definitions/rerun/archetypes/graph_edges.fbs b/crates/store/re_types/definitions/rerun/archetypes/graph_edges.fbs index f4e6a7a5988d..a20ea2d39fa1 100644 --- a/crates/store/re_types/definitions/rerun/archetypes/graph_edges.fbs +++ b/crates/store/re_types/definitions/rerun/archetypes/graph_edges.fbs @@ -2,14 +2,12 @@ namespace rerun.archetypes; // --- -// TODO(ab): Add images to snippets. - /// A list of edges in a graph. /// /// By default, edges are undirected. /// -/// \example archetypes/graph_undirected !api title="Simple undirected graph" image="" -/// \example archetypes/graph_directed !api title="Simple directed graph" image="" +/// \example archetypes/graph_undirected !api title="Simple undirected graph" image="https://static.rerun.io/graph_undirected/15f46bec77452a8c6220558e4403b99cac188e2e/1200w.png" +/// \example archetypes/graph_directed !api title="Simple directed graph" image="https://static.rerun.io/graph_directed/ca29a37b65e1e0b6482251dce401982a0bc568fa/1200w.png" table GraphEdges ( "attr.docs.category": "Graph", "attr.docs.unreleased", diff --git a/crates/store/re_types/definitions/rerun/archetypes/graph_nodes.fbs b/crates/store/re_types/definitions/rerun/archetypes/graph_nodes.fbs index bf31f6fe5efa..7e7ddb535164 100644 --- a/crates/store/re_types/definitions/rerun/archetypes/graph_nodes.fbs +++ b/crates/store/re_types/definitions/rerun/archetypes/graph_nodes.fbs @@ -2,12 +2,10 @@ namespace rerun.archetypes; // --- -// TODO(ab): Add images to snippets. - /// A list of nodes in a graph with optional labels, colors, etc. /// -/// \example archetypes/graph_undirected !api title="Simple undirected graph" image="" -/// \example archetypes/graph_directed !api title="Simple directed graph" image="" +/// \example archetypes/graph_undirected !api title="Simple undirected graph" image="https://static.rerun.io/graph_undirected/15f46bec77452a8c6220558e4403b99cac188e2e/1200w.png" +/// \example archetypes/graph_directed !api title="Simple directed graph" image="https://static.rerun.io/graph_directed/ca29a37b65e1e0b6482251dce401982a0bc568fa/1200w.png" table GraphNodes ( "attr.docs.category": "Graph", "attr.docs.unreleased", diff --git a/crates/viewer/re_view_graph/src/properties.rs b/crates/viewer/re_view_graph/src/properties.rs index bbad71903532..3a99d6c777f0 100644 --- a/crates/viewer/re_view_graph/src/properties.rs +++ b/crates/viewer/re_view_graph/src/properties.rs @@ -6,6 +6,7 @@ use re_types::{ components::Position2D, Archetype as _, }; +use re_ui::zoom_pan_area::fit_to_rect_in_scene; use re_viewer_context::{TypedComponentFallbackProvider, ViewStateExt as _}; use crate::{ui::GraphViewState, GraphView}; @@ -21,7 +22,14 @@ impl TypedComponentFallbackProvider for GraphView { }; match state.layout_state.bounding_rect() { - Some(rect) if valid_bound(&rect) => rect.into(), + Some(rect) if valid_bound(&rect) => { + if let Some(rect_in_ui) = state.rect_in_ui { + let ui_from_world = fit_to_rect_in_scene(rect_in_ui, rect); + (ui_from_world.inverse() * rect_in_ui).into() + } else { + rect.into() + } + } _ => VisualBounds2D::default(), } } diff --git a/crates/viewer/re_view_graph/src/ui/state.rs b/crates/viewer/re_view_graph/src/ui/state.rs index 89cc2d232e6a..05eff3718fbc 100644 --- a/crates/viewer/re_view_graph/src/ui/state.rs +++ b/crates/viewer/re_view_graph/src/ui/state.rs @@ -1,4 +1,4 @@ -use egui::Rect; +use egui::{emath::TSTransform, Rect}; use re_format::format_f32; use re_types::blueprint::components::VisualBounds2D; use re_ui::UiExt; @@ -16,6 +16,8 @@ pub struct GraphViewState { pub show_debug: bool, pub visual_bounds: Option, + pub ui_from_world: Option, + pub rect_in_ui: Option, } impl GraphViewState { diff --git a/crates/viewer/re_view_graph/src/view.rs b/crates/viewer/re_view_graph/src/view.rs index ff18e5fde607..eaf2068663ee 100644 --- a/crates/viewer/re_view_graph/src/view.rs +++ b/crates/viewer/re_view_graph/src/view.rs @@ -168,6 +168,8 @@ Display a graph of nodes and edges. let state = state.downcast_mut::()?; + let params = ForceLayoutParams::get(ctx, query, self, state)?; + let bounds_property = ViewProperty::from_archetype::( ctx.blueprint_db(), ctx.blueprint_query, @@ -176,17 +178,28 @@ Display a graph of nodes and edges. let rect_in_scene: blueprint::components::VisualBounds2D = bounds_property.component_or_fallback(ctx, self, state)?; - let params = ForceLayoutParams::get(ctx, query, self, state)?; - - let rect_in_ui = ui.max_rect(); - + // Perform all layout-related tasks. let request = LayoutRequest::from_graphs(graphs.iter()); let layout_was_empty = state.layout_state.is_none(); let layout = state.layout_state.get(request, params); - let mut ui_from_world = fit_to_rect_in_scene(rect_in_ui, rect_in_scene.into()); + // Prepare the view and the transformations. + let prev_rect_in_ui = state.rect_in_ui; + let rect_in_ui = *state.rect_in_ui.insert(ui.max_rect()); + + let ui_from_world = state + .ui_from_world + .get_or_insert_with(|| fit_to_rect_in_scene(rect_in_ui, rect_in_scene.into())); + + // We ensure that the view's center is kept during resizing. + if let Some(prev) = prev_rect_in_ui { + if prev != rect_in_ui { + let delta = rect_in_ui.center() - prev.center(); + ui_from_world.translation += delta; + } + } - let resp = zoom_pan_area(ui, rect_in_ui, &mut ui_from_world, |ui| { + let resp = zoom_pan_area(ui, rect_in_ui, ui_from_world, |ui| { let mut world_bounding_rect = egui::Rect::NOTHING; for graph in &graphs { @@ -205,6 +218,7 @@ Display a graph of nodes and edges. blueprint::components::VisualBounds2D::from(ui_from_world.inverse() * rect_in_ui); if resp.double_clicked() || layout_was_empty { bounds_property.reset_blueprint_component::(ctx); + state.ui_from_world = None; } else if rect_in_scene != updated_rect_in_scene { bounds_property.save_blueprint_component(ctx, &updated_rect_in_scene); } diff --git a/docs/content/reference/types/archetypes/graph_edges.md b/docs/content/reference/types/archetypes/graph_edges.md index 8a14d6c11d70..47dc62ca7791 100644 --- a/docs/content/reference/types/archetypes/graph_edges.md +++ b/docs/content/reference/types/archetypes/graph_edges.md @@ -31,11 +31,23 @@ By default, edges are undirected. snippet: archetypes/graph_undirected - + + + + + + + ### Simple directed graph snippet: archetypes/graph_directed - + + + + + + + diff --git a/docs/content/reference/types/archetypes/graph_nodes.md b/docs/content/reference/types/archetypes/graph_nodes.md index 1bc0f1589ff2..c5b6d38ebab0 100644 --- a/docs/content/reference/types/archetypes/graph_nodes.md +++ b/docs/content/reference/types/archetypes/graph_nodes.md @@ -29,11 +29,23 @@ A list of nodes in a graph with optional labels, colors, etc. snippet: archetypes/graph_undirected - + + + + + + + ### Simple directed graph snippet: archetypes/graph_directed - + + + + + + + diff --git a/examples/rust/chess_robby_fischer/README.md b/examples/rust/chess_robby_fischer/README.md index a1309eae90fd..cdefec85040c 100644 --- a/examples/rust/chess_robby_fischer/README.md +++ b/examples/rust/chess_robby_fischer/README.md @@ -279,7 +279,7 @@ import rerun as rr import rerun.blueprint as rrb import argparse -space_view_defaults = [ +view_defaults = [ rr.components.AxisLength(0.0), # To hide the axes of all the transformations. rr.components.ImagePlaneDistance(0.3), ] @@ -305,11 +305,11 @@ blueprint = rrb.Blueprint( rrb.Spatial3DView( origin="/arm.urdf/base_link/glid_platta_1/bas_1/gemensam_vagg_1/botten_snurr_1/kortarm_kopia_1/led_1/led_axel_1/lang_arm_1/mount_1/ram_1", contents="/**", - defaults=space_view_defaults + defaults=view_defaults ) ), rrb.Spatial3DView( - defaults=space_view_defaults + defaults=view_defaults ), column_shares=[2,2,3] ), diff --git a/examples/rust/graph_lattice/README.md b/examples/rust/graph_lattice/README.md index c714a94be6e1..a4ebaa3a477f 100644 --- a/examples/rust/graph_lattice/README.md +++ b/examples/rust/graph_lattice/README.md @@ -1,3 +1,28 @@ -# graph_lattice + -Demonstrates graph layout of a lattice without explicit positions. +This example shows different attributes that you can associate with nodes in a graph. +Since no explicit positions are passed for the nodes, Rerun will layout the graph automatically. + + + + + + + + + +## Used Rerun types +[`GraphNodes`](https://www.rerun.io/docs/reference/types/archetypes/graph_nodes?speculative-link), +[`GraphEdges`](https://www.rerun.io/docs/reference/types/archetypes/graph_edges?speculative-link) + +## Run the code + +```bash +cargo run --release +``` diff --git a/rerun_cpp/src/rerun/blueprint.hpp b/rerun_cpp/src/rerun/blueprint.hpp deleted file mode 100644 index 6bcce6fd744d..000000000000 --- a/rerun_cpp/src/rerun/blueprint.hpp +++ /dev/null @@ -1,11 +0,0 @@ -// DO NOT EDIT! This file was auto-generated by crates/build/re_types_builder/src/codegen/cpp/mod.rs - -#pragma once - -#include "blueprint/auto_views.hpp" -#include "blueprint/entity_properties_component.hpp" -#include "blueprint/panel_view.hpp" -#include "blueprint/query_expressions.hpp" -#include "blueprint/space_view_component.hpp" -#include "blueprint/space_view_maximized.hpp" -#include "blueprint/viewport_layout.hpp" diff --git a/rerun_py/docs/gen_common_index.py b/rerun_py/docs/gen_common_index.py index da8d9dc6c073..4c106a2e6ce4 100755 --- a/rerun_py/docs/gen_common_index.py +++ b/rerun_py/docs/gen_common_index.py @@ -380,17 +380,15 @@ class Section: mod_path="rerun.utilities", show_submodules=True, ), - Section( - title="Experimental", - func_list=[ - "add_space_view", - "new_blueprint", - "set_auto_views", - "set_panels", - ], - show_tables=False, - mod_path="rerun.experimental", - ), + # We don't have any experimental apis right now, but when you add one again, you should add this here: + # Section( + # title="Experimental", + # func_list=[ + # "my_experimental_function", + # ], + # show_tables=False, + # mod_path="rerun.experimental", + # ), ] diff --git a/rerun_py/rerun_sdk/rerun/blueprint/api.py b/rerun_py/rerun_sdk/rerun/blueprint/api.py index 9727a50b19df..c40b442ef1d2 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/api.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/api.py @@ -98,7 +98,7 @@ def blueprint_path(self) -> str: Note that although this is an `EntityPath`, is scoped to the blueprint tree and not a part of the regular data hierarchy. """ - return f"space_view/{self.id}" + return f"view/{self.id}" def to_container(self) -> Container: """Convert this view to a container.""" diff --git a/rerun_py/tests/unit/test_container_blueprint.py b/rerun_py/tests/unit/test_container_blueprint.py index c034ce7b5a99..494644d7e970 100644 --- a/rerun_py/tests/unit/test_container_blueprint.py +++ b/rerun_py/tests/unit/test_container_blueprint.py @@ -36,8 +36,8 @@ def test_container_blueprint() -> None: contents_arrays: Sequence[Any] = [ None, [], - ["space_view/1234", "container/5678"], - [EntityPath("space_view/1234"), EntityPath("container/5678")], + ["view/1234", "container/5678"], + [EntityPath("view/1234"), EntityPath("container/5678")], ] col_shares_arrays = [ @@ -54,9 +54,9 @@ def test_container_blueprint() -> None: active_tab_arrays = [ None, - "space_view/1234", - ActiveTab("space_view/1234"), - ActiveTab(EntityPath("space_view/1234")), + "view/1234", + ActiveTab("view/1234"), + ActiveTab(EntityPath("view/1234")), ] visible_arrays = [ diff --git a/rerun_py/tests/unit/test_view_contents.py b/rerun_py/tests/unit/test_view_contents.py index 93aa0e4ba5c2..ee54d77b4d1a 100644 --- a/rerun_py/tests/unit/test_view_contents.py +++ b/rerun_py/tests/unit/test_view_contents.py @@ -8,7 +8,7 @@ from rerun.datatypes.utf8 import Utf8ArrayLike -def test_space_view_contents() -> None: +def test_view_contents() -> None: query_array = [ [ "+ /**",