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

New debug option to show an actual timeline for the Blueprint #4609

Merged
merged 23 commits into from
Jan 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
0e71c3d
Swap out the whole timeline panel for the blueprint store
jleibs Dec 21, 2023
33d1ce5
Switch blueprint to log with real timepoints
jleibs Dec 21, 2023
2d5e400
Use correct time_ctrl for determining visibillity
jleibs Dec 21, 2023
b7e054f
Use correct query for blueprint entities
jleibs Dec 21, 2023
6d075b1
Use the blueprint time_ctrl to drive the blueprint queries
jleibs Dec 22, 2023
810de30
Make the blueprint timeline useful with an option to disable GC
jleibs Dec 22, 2023
3c91af7
Fix rebase for blueprint timepoint
jleibs Jan 16, 2024
7a5e641
Cleanup menu / config options
jleibs Jan 16, 2024
46af2f8
Fix time state updates
jleibs Jan 16, 2024
f6902ce
Fix build error in release
jleibs Jan 16, 2024
03416d0
Merge branch 'main' into jleibs/blueprint_timeline
jleibs Jan 18, 2024
9d88924
Make the blueprint inspection panel a secondary timeline panel
jleibs Jan 18, 2024
3b8e773
GC the blueprints more frequently
jleibs Jan 18, 2024
5215ad9
Switch blueprint gc to a radio button
jleibs Jan 18, 2024
d773da7
Comment explaining why we can't update the blueprint while we're insp…
jleibs Jan 18, 2024
b2a6047
Use re_ui.radio_value
jleibs Jan 18, 2024
af8cc5d
Plumb store through data_ui
jleibs Jan 18, 2024
072118b
On the timeline view derive store from the TimePanel source
jleibs Jan 18, 2024
c532ed7
More plumbing of queries and stores
jleibs Jan 18, 2024
ea96bb2
Limit entity-path store+query guessing to the selection_panel impleme…
jleibs Jan 18, 2024
b7a5014
Renames and docstrings
jleibs Jan 18, 2024
23ee728
Merge branch 'main' into jleibs/blueprint_timeline
jleibs Jan 18, 2024
79e395a
Title the blueprint streams accordingly
jleibs Jan 18, 2024
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
3 changes: 3 additions & 0 deletions crates/re_data_ui/src/annotation_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ impl crate::EntityDataUi for re_types::components::ClassId {
verbosity: re_viewer_context::UiVerbosity,
entity_path: &re_log_types::EntityPath,
query: &re_data_store::LatestAtQuery,
_store: &re_data_store::DataStore,
) {
let annotations = crate::annotations(ctx, query, entity_path);
let class = annotations
Expand Down Expand Up @@ -62,6 +63,7 @@ impl crate::EntityDataUi for re_types::components::KeypointId {
_verbosity: re_viewer_context::UiVerbosity,
entity_path: &re_log_types::EntityPath,
query: &re_data_store::LatestAtQuery,
_store: &re_data_store::DataStore,
) {
if let Some(info) = annotation_info(ctx, entity_path, query, self.0) {
ui.horizontal(|ui| {
Expand Down Expand Up @@ -100,6 +102,7 @@ impl DataUi for AnnotationContext {
ui: &mut egui::Ui,
verbosity: UiVerbosity,
_query: &re_data_store::LatestAtQuery,
_store: &re_data_store::DataStore,
) {
match verbosity {
UiVerbosity::Small | UiVerbosity::Reduced => {
Expand Down
22 changes: 16 additions & 6 deletions crates/re_data_ui/src/blueprint_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,17 @@ impl DataUi for IncludedQueries {
_ctx: &ViewerContext<'_>,
ui: &mut egui::Ui,
verbosity: UiVerbosity,
_query: &re_data_store::LatestAtQuery,
query: &re_data_store::LatestAtQuery,
store: &re_data_store::DataStore,
) {
match verbosity {
UiVerbosity::Small => {
ui.label(format!("{} Queries", self.0.len()));
}
UiVerbosity::Full | UiVerbosity::LimitHeight | UiVerbosity::Reduced => {
for query in &self.0 {
let query: DataQueryId = (*query).into();
query.data_ui(_ctx, ui, verbosity, _query);
for data_query in &self.0 {
let data_query: DataQueryId = (*data_query).into();
data_query.data_ui(_ctx, ui, verbosity, query, store);
ui.end_row();
}
}
Expand All @@ -36,8 +37,17 @@ impl<T: BlueprintIdRegistry> DataUi for BlueprintId<T> {
ctx: &ViewerContext<'_>,
ui: &mut egui::Ui,
_verbosity: UiVerbosity,
_query: &re_data_store::LatestAtQuery,
query: &re_data_store::LatestAtQuery,
store: &re_data_store::DataStore,
) {
entity_path_button_to(ctx, ui, None, &self.as_entity_path(), self.to_string());
entity_path_button_to(
ctx,
query,
store,
ui,
None,
&self.as_entity_path(),
self.to_string(),
);
}
}
5 changes: 5 additions & 0 deletions crates/re_data_ui/src/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ impl DataUi for EntityComponentWithInstances {
ui: &mut egui::Ui,
verbosity: UiVerbosity,
query: &re_data_store::LatestAtQuery,
store: &re_data_store::DataStore,
) {
re_tracing::profile_function!(self.component_name().full_name());

Expand Down Expand Up @@ -84,6 +85,7 @@ impl DataUi for EntityComponentWithInstances {
ui,
verbosity,
query,
store,
&self.entity_path,
&self.component_data,
instance_key,
Expand Down Expand Up @@ -120,6 +122,8 @@ impl DataUi for EntityComponentWithInstances {
InstancePath::instance(self.entity_path.clone(), *instance_key);
item_ui::instance_path_button_to(
ctx,
query,
store,
ui,
None,
&instance_path,
Expand All @@ -132,6 +136,7 @@ impl DataUi for EntityComponentWithInstances {
ui,
UiVerbosity::Small,
query,
store,
&self.entity_path,
&self.component_data,
instance_key,
Expand Down
11 changes: 2 additions & 9 deletions crates/re_data_ui/src/component_path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,13 @@ impl DataUi for ComponentPath {
ui: &mut egui::Ui,
verbosity: UiVerbosity,
query: &re_data_store::LatestAtQuery,
store: &re_data_store::DataStore,
) {
let Self {
entity_path,
component_name,
} = self;

let store = if ctx.app_options.show_blueprint_in_timeline
&& ctx.store_context.blueprint.is_logged_entity(entity_path)
{
ctx.store_context.blueprint.store()
} else {
ctx.entity_db.store()
};

if let Some(archetype_name) = component_name.indicator_component_archetype() {
ui.label(format!(
"Indicator component for the {archetype_name} archetype"
Expand All @@ -35,7 +28,7 @@ impl DataUi for ComponentPath {
entity_path: self.entity_path.clone(),
component_data,
}
.data_ui(ctx, ui, verbosity, query);
.data_ui(ctx, ui, verbosity, query, store);
} else if let Some(entity_tree) = ctx.entity_db.tree().subtree(entity_path) {
if entity_tree.entity.components.contains_key(component_name) {
ui.label("<unset>");
Expand Down
8 changes: 5 additions & 3 deletions crates/re_data_ui/src/component_ui_registry.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use re_data_store::LatestAtQuery;
use re_data_store::{DataStore, LatestAtQuery};
use re_log_types::{external::arrow2, EntityPath};
use re_query::ComponentWithInstances;
use re_types::external::arrow2::array::Utf8Array;
Expand Down Expand Up @@ -37,11 +37,11 @@ pub fn add_to_registry<C: EntityDataUi + re_types::Component>(registry: &mut Com
registry.add(
C::name(),
Box::new(
|ctx, ui, verbosity, query, entity_path, component, instance| match component
|ctx, ui, verbosity, query, store, entity_path, component, instance| match component
.lookup::<C>(instance)
{
Ok(component) => {
component.entity_data_ui(ctx, ui, verbosity, entity_path, query);
component.entity_data_ui(ctx, ui, verbosity, entity_path, query, store);
}
Err(re_query::QueryError::ComponentNotFound(_)) => {
ui.weak("(not found)");
Expand All @@ -54,11 +54,13 @@ pub fn add_to_registry<C: EntityDataUi + re_types::Component>(registry: &mut Com
);
}

#[allow(clippy::too_many_arguments)]
fn fallback_component_ui(
_ctx: &ViewerContext<'_>,
ui: &mut egui::Ui,
verbosity: UiVerbosity,
_query: &LatestAtQuery,
_store: &DataStore,
_entity_path: &EntityPath,
component: &ComponentWithInstances,
instance_key: &re_types::components::InstanceKey,
Expand Down
12 changes: 11 additions & 1 deletion crates/re_data_ui/src/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ impl DataUi for [u8; 4] {
ui: &mut egui::Ui,
_verbosity: UiVerbosity,
_query: &re_data_store::LatestAtQuery,
_store: &re_data_store::DataStore,
) {
let [r, g, b, a] = self;
let color = egui::Color32::from_rgba_unmultiplied(*r, *g, *b, *a);
Expand All @@ -38,6 +39,7 @@ impl DataUi for Color {
ui: &mut egui::Ui,
_verbosity: UiVerbosity,
_query: &re_data_store::LatestAtQuery,
_store: &re_data_store::DataStore,
) {
let [r, g, b, a] = self.to_array();
let color = egui::Color32::from_rgba_unmultiplied(r, g, b, a);
Expand All @@ -58,6 +60,7 @@ impl DataUi for ViewCoordinates {
ui: &mut egui::Ui,
verbosity: UiVerbosity,
_query: &re_data_store::LatestAtQuery,
_store: &re_data_store::DataStore,
) {
match verbosity {
UiVerbosity::Small => {
Expand All @@ -77,6 +80,7 @@ impl DataUi for re_types::datatypes::Mat3x3 {
ui: &mut egui::Ui,
_verbosity: UiVerbosity,
_query: &re_data_store::LatestAtQuery,
_store: &re_data_store::DataStore,
) {
egui::Grid::new("mat3").num_columns(3).show(ui, |ui| {
ui.monospace(self[0].to_string());
Expand Down Expand Up @@ -104,6 +108,7 @@ impl DataUi for re_types::datatypes::Vec2D {
ui: &mut egui::Ui,
_verbosity: UiVerbosity,
_query: &re_data_store::LatestAtQuery,
_store: &re_data_store::DataStore,
) {
ui.label(self.to_string());
}
Expand All @@ -116,6 +121,7 @@ impl DataUi for re_types::datatypes::Vec3D {
ui: &mut egui::Ui,
_verbosity: UiVerbosity,
_query: &re_data_store::LatestAtQuery,
_store: &re_data_store::DataStore,
) {
ui.label(self.to_string());
}
Expand All @@ -128,6 +134,7 @@ impl DataUi for LineStrip2D {
ui: &mut egui::Ui,
verbosity: UiVerbosity,
_query: &re_data_store::LatestAtQuery,
_store: &re_data_store::DataStore,
) {
match verbosity {
UiVerbosity::Small | UiVerbosity::Reduced => {
Expand Down Expand Up @@ -174,6 +181,7 @@ impl DataUi for LineStrip3D {
ui: &mut egui::Ui,
verbosity: UiVerbosity,
_query: &re_data_store::LatestAtQuery,
_store: &re_data_store::DataStore,
) {
match verbosity {
UiVerbosity::Small | UiVerbosity::Reduced => {
Expand Down Expand Up @@ -226,10 +234,11 @@ impl DataUi for Material {
ui: &mut egui::Ui,
verbosity: UiVerbosity,
query: &re_data_store::LatestAtQuery,
store: &re_data_store::DataStore,
) {
let show_optional_albedo_factor = |ui: &mut egui::Ui| {
if let Some(albedo_factor) = self.albedo_factor {
Color(albedo_factor).data_ui(ctx, ui, verbosity, query);
Color(albedo_factor).data_ui(ctx, ui, verbosity, query, store);
} else {
ui.weak("(empty)");
}
Expand Down Expand Up @@ -257,6 +266,7 @@ impl DataUi for MeshProperties {
ui: &mut egui::Ui,
verbosity: UiVerbosity,
_query: &re_data_store::LatestAtQuery,
_store: &re_data_store::DataStore,
) {
let show_optional_indices = |ui: &mut egui::Ui| {
if let Some(indices) = self.indices.as_ref() {
Expand Down
1 change: 1 addition & 0 deletions crates/re_data_ui/src/entity_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ impl crate::DataUi for re_entity_db::EntityDb {
ui: &mut egui::Ui,
verbosity: re_viewer_context::UiVerbosity,
_query: &re_data_store::LatestAtQuery,
_store: &re_data_store::DataStore,
) {
let re_ui = &ctx.re_ui;

Expand Down
3 changes: 2 additions & 1 deletion crates/re_data_ui/src/entity_path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ impl DataUi for re_entity_db::EntityPath {
ui: &mut egui::Ui,
verbosity: UiVerbosity,
query: &re_data_store::LatestAtQuery,
store: &re_data_store::DataStore,
) {
InstancePath::entity_splat(self.clone()).data_ui(ctx, ui, verbosity, query);
InstancePath::entity_splat(self.clone()).data_ui(ctx, ui, verbosity, query, store);
}
}
9 changes: 7 additions & 2 deletions crates/re_data_ui/src/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ impl EntityDataUi for re_types::components::TensorData {
verbosity: UiVerbosity,
entity_path: &re_log_types::EntityPath,
query: &re_data_store::LatestAtQuery,
store: &re_data_store::DataStore,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NOTE: this is a personal style preference, so feel free to ignore.

When deciding parameters order, I usually go with "environmental first, specific last". ctx is basically always the same, so it is always first. ui is likewise part of the environment (its where we happen to add widgets). I would therefore have put store before verbosity.

This helps keep the argument order somewhat consistent across the code base (ctx, ui, store, entity_path, component_path, time, …). Of course, there is a lot of room for interpretation here.

Also, it'd be a pain in the ass to change this now, so feel free not to change anything - I just wanted to spread what I consider a good practice :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, you've mentioned that before and I had the thought in my head while writing this code. If I was adding both query and store, I would have been more inclined to add it right after ctx at the beginning. But I found it easier to keep query & store together as a pair for this.

Open to doing parameter order reshuffling in another refactor-only PR and moving them both to the front. I'm also inclined to introduce some kind of "DataQueryContext" that combines those things just to cut down on all the arguments, which might also eventually include things like caches and override stacks.

) {
re_tracing::profile_function!();

Expand All @@ -45,6 +46,8 @@ impl EntityDataUi for re_types::components::TensorData {
let annotations = crate::annotations(ctx, query, entity_path);
tensor_ui(
ctx,
query,
store,
ui,
verbosity,
entity_path,
Expand All @@ -64,6 +67,8 @@ impl EntityDataUi for re_types::components::TensorData {
#[allow(clippy::too_many_arguments)]
fn tensor_ui(
ctx: &ViewerContext<'_>,
query: &re_data_store::LatestAtQuery,
store: &re_data_store::DataStore,
ui: &mut egui::Ui,
verbosity: UiVerbosity,
entity_path: &re_entity_db::EntityPath,
Expand All @@ -79,12 +84,12 @@ fn tensor_ui(
.entry(|c: &mut TensorStatsCache| c.entry(tensor_data_row_id, tensor));
let debug_name = entity_path.to_string();

let meaning = image_meaning_for_entity(entity_path, ctx);
let meaning = image_meaning_for_entity(entity_path, query, store);

let meter = if meaning == TensorDataMeaning::Depth {
ctx.entity_db
.store()
.query_latest_component::<DepthMeter>(entity_path, &ctx.current_query())
.query_latest_component::<DepthMeter>(entity_path, query)
.map(|meter| meter.value.0)
} else {
None
Expand Down
7 changes: 3 additions & 4 deletions crates/re_data_ui/src/image_meaning.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@ use re_types::{
tensor_data::TensorDataMeaning,
Archetype,
};
use re_viewer_context::ViewerContext;

pub fn image_meaning_for_entity(
entity_path: &EntityPath,
ctx: &ViewerContext<'_>,
query: &re_data_store::LatestAtQuery,
store: &re_data_store::DataStore,
) -> TensorDataMeaning {
let store = ctx.entity_db.store();
let timeline = &ctx.current_query().timeline;
let timeline = &query.timeline;
if store.entity_has_component(timeline, entity_path, &DepthImage::indicator().name()) {
TensorDataMeaning::Depth
} else if store.entity_has_component(
Expand Down
12 changes: 3 additions & 9 deletions crates/re_data_ui/src/instance_path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,13 @@ impl DataUi for InstancePath {
ui: &mut egui::Ui,
verbosity: UiVerbosity,
query: &re_data_store::LatestAtQuery,
store: &re_data_store::DataStore,
) {
let Self {
entity_path,
instance_key,
} = self;

let store = if ctx.app_options.show_blueprint_in_timeline
&& ctx.store_context.blueprint.is_logged_entity(entity_path)
{
ctx.store_context.blueprint.store()
} else {
ctx.entity_db.store()
};

let Some(components) = store.all_components(&query.timeline, entity_path) else {
if ctx.entity_db.is_known_entity(entity_path) {
// This is fine - e.g. we're looking at `/world` and the user has only logged to `/world/car`.
Expand Down Expand Up @@ -83,13 +76,14 @@ impl DataUi for InstancePath {
entity_path: entity_path.clone(),
component_data,
}
.data_ui(ctx, ui, UiVerbosity::Small, query);
.data_ui(ctx, ui, UiVerbosity::Small, query, store);
} else {
ctx.component_ui_registry.ui(
ctx,
ui,
UiVerbosity::Small,
query,
store,
entity_path,
&component_data,
instance_key,
Expand Down
Loading
Loading