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 = [ [ "+ /**",