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

Set visual 2D bounds from code #6127

Merged
merged 20 commits into from Apr 29, 2024
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions crates/re_entity_db/src/entity_db.rs
Expand Up @@ -232,6 +232,14 @@ impl EntityDb {
}
}

/// Get the latest index and value for a given dense [`re_types_core::Component`].
///
/// This assumes that the row we get from the store contains at most one instance for this
/// component; it will log a warning otherwise.
///
/// This should only be used for "mono-components" such as `Transform` and `Tensor`.
///
/// This is a best-effort helper, it will merely log errors on failure.
#[inline]
pub fn latest_at_component<C: re_types_core::Component>(
&self,
Expand All @@ -246,6 +254,14 @@ impl EntityDb {
)
}

/// Get the latest index and value for a given dense [`re_types_core::Component`].
///
/// This assumes that the row we get from the store contains at most one instance for this
/// component; it will log a warning otherwise.
///
/// This should only be used for "mono-components" such as `Transform` and `Tensor`.
///
/// This is a best-effort helper, and will quietly swallow any errors.
#[inline]
pub fn latest_at_component_quiet<C: re_types_core::Component>(
&self,
Expand Down
79 changes: 47 additions & 32 deletions crates/re_query/src/latest_at/helpers.rs
Expand Up @@ -62,7 +62,7 @@ impl LatestAtComponentResults {

/// Returns the component data of the single instance.
///
/// This assumes that the row we get from the store only contains a single instance for this
/// This assumes that the row we get from the store contains at most one instance for this
/// component; it will log a warning otherwise.
///
/// This should only be used for "mono-components" such as `Transform` and `Tensor`.
Expand All @@ -77,14 +77,19 @@ impl LatestAtComponentResults {
re_log::debug_once!("Couldn't deserialize {component_name}: promise still pending",);
None
}
PromiseResult::Ready(data) if data.len() == 1 => Some(data[0].clone()),
PromiseResult::Ready(data) => {
Copy link
Member

Choose a reason for hiding this comment

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

ah so the warning we saw was simply a bug

re_log::log_once!(
level,
"Couldn't deserialize {component_name}: not a mono-batch (length: {})",
data.len(),
);
None
match data.len() {
0 => {
None // Empty list = no data.
}
1 => Some(data[0].clone()),
len => {
re_log::log_once!(level,
"Couldn't deserialize {component_name}: not a mono-batch (length: {len})"
);
None
}
}
}
PromiseResult::Error(err) => {
re_log::log_once!(
Expand All @@ -99,7 +104,7 @@ impl LatestAtComponentResults {

/// Returns the component data of the single instance as an arrow array.
///
/// This assumes that the row we get from the store only contains a single instance for this
/// This assumes that the row we get from the store contains at most one instance for this
/// component; it will log a warning otherwise.
///
/// This should only be used for "mono-components" such as `Transform` and `Tensor`.
Expand All @@ -118,16 +123,20 @@ impl LatestAtComponentResults {
re_log::debug_once!("Couldn't get {component_name}: promise still pending");
None
}
PromiseResult::Ready(cell) if cell.as_arrow_ref().len() == 1 => {
Some(cell.as_arrow_ref().sliced(0, 1))
}
PromiseResult::Ready(cell) => {
re_log::log_once!(
level,
"Couldn't get {component_name}: not a mono-batch (length: {})",
cell.as_arrow_ref().len(),
);
None
match cell.as_arrow_ref().len() {
0 => {
None // Empty list = no data.
}
1 => Some(cell.as_arrow_ref().sliced(0, 1)),
len => {
re_log::log_once!(
level,
"Couldn't get {component_name}: not a mono-batch (length: {len})",
);
None
}
}
}
PromiseResult::Error(err) => {
re_log::log_once!(
Expand Down Expand Up @@ -272,7 +281,7 @@ impl Caches {
///
/// Returns `None` if the data is a promise that has yet to be resolved.
///
/// This assumes that the row we get from the store only contains a single instance for this
/// This assumes that the row we get from the store contains at most one instance for this
/// component; it will generate a log message of `level` otherwise.
///
/// This should only be used for "mono-components" such as `Transform` and `Tensor`.
Expand Down Expand Up @@ -303,18 +312,24 @@ impl Caches {
);
None
}
PromiseResult::Ready(data) if data.len() == 1 => Some(LatestAtMonoResult {
index,
value: data[0].clone(),
}),
PromiseResult::Ready(data) => {
re_log::log_once!(
level,
"Couldn't deserialize {entity_path}:{} @ {data_time:?}#{row_id}: not a mono-batch (length: {})",
C::name(),
data.len(),
);
None
match data.len() {
0 => {
None // Empty list = no data.
}
1 => Some(LatestAtMonoResult {
index,
value: data[0].clone(),
}),
len => {
re_log::log_once!(
level,
"Couldn't deserialize {entity_path}:{} @ {data_time:?}#{row_id}: not a mono-batch (length: {len})",
C::name(),
);
None
}
}
}
PromiseResult::Error(err) => {
re_log::log_once!(
Expand All @@ -330,7 +345,7 @@ impl Caches {

/// Get the latest index and value for a given dense [`re_types_core::Component`].
///
/// This assumes that the row we get from the store only contains a single instance for this
/// This assumes that the row we get from the store contains at most one instance for this
/// component; it will log a warning otherwise.
///
/// This should only be used for "mono-components" such as `Transform` and `Tensor`.
Expand All @@ -355,7 +370,7 @@ impl Caches {

/// Get the latest index and value for a given dense [`re_types_core::Component`].
///
/// This assumes that the row we get from the store only contains a single instance for this
/// This assumes that the row we get from the store contains at most one instance for this
/// component; it will return None and log a debug message otherwise.
///
/// This should only be used for "mono-components" such as `Transform` and `Tensor`.
Expand Down
1 change: 1 addition & 0 deletions crates/re_query/src/latest_at/to_archetype/.gitattributes

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/re_query/src/latest_at/to_archetype/mod.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

44 changes: 44 additions & 0 deletions crates/re_query/src/latest_at/to_archetype/visual_bounds.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions crates/re_space_view/src/lib.rs
Expand Up @@ -18,8 +18,9 @@ pub use screenshot::ScreenshotMode;
pub use space_view::SpaceViewBlueprint;
pub use space_view_contents::SpaceViewContents;
pub use sub_archetypes::{
entity_path_for_space_view_sub_archetype, query_space_view_sub_archetype,
query_space_view_sub_archetype_or_default, space_view_sub_archetype,
edit_blueprint_component, entity_path_for_space_view_sub_archetype, get_blueprint_component,
query_space_view_sub_archetype, query_space_view_sub_archetype_or_default,
space_view_sub_archetype,
};
pub use visual_time_range::{
query_visual_history, time_range_boundary_to_visible_history_boundary,
Expand Down
4 changes: 4 additions & 0 deletions crates/re_space_view/src/space_view.rs
Expand Up @@ -553,6 +553,7 @@ mod tests {
let ctx = StoreContext {
app_id: re_log_types::ApplicationId::unknown(),
blueprint: &blueprint,
default_blueprint: None,
recording: &recording,
bundle: &Default::default(),
hub: &re_viewer_context::StoreHub::test_hub(),
Expand Down Expand Up @@ -597,6 +598,7 @@ mod tests {
let ctx = StoreContext {
app_id: re_log_types::ApplicationId::unknown(),
blueprint: &blueprint,
default_blueprint: None,
recording: &recording,
bundle: &Default::default(),
hub: &re_viewer_context::StoreHub::test_hub(),
Expand Down Expand Up @@ -647,6 +649,7 @@ mod tests {
let ctx = StoreContext {
app_id: re_log_types::ApplicationId::unknown(),
blueprint: &blueprint,
default_blueprint: None,
recording: &recording,
bundle: &Default::default(),
hub: &re_viewer_context::StoreHub::test_hub(),
Expand Down Expand Up @@ -920,6 +923,7 @@ mod tests {
let ctx = StoreContext {
app_id: re_log_types::ApplicationId::unknown(),
blueprint: &blueprint,
default_blueprint: None,
recording: &recording,
bundle: &Default::default(),
hub: &re_viewer_context::StoreHub::test_hub(),
Expand Down
1 change: 1 addition & 0 deletions crates/re_space_view/src/space_view_contents.rs
Expand Up @@ -695,6 +695,7 @@ mod tests {
let ctx = StoreContext {
app_id: re_log_types::ApplicationId::unknown(),
blueprint: &blueprint,
default_blueprint: None,
recording: &recording,
bundle: &Default::default(),
hub: &StoreHub::test_hub(),
Expand Down
58 changes: 57 additions & 1 deletion crates/re_space_view/src/sub_archetypes.rs
Expand Up @@ -5,7 +5,7 @@ use re_entity_db::{
};
use re_log_types::EntityPath;
use re_types::Archetype;
use re_viewer_context::{external::re_entity_db::EntityTree, SpaceViewId};
use re_viewer_context::{external::re_entity_db::EntityTree, SpaceViewId, ViewerContext};

pub fn entity_path_for_space_view_sub_archetype<T: Archetype>(
space_view_id: SpaceViewId,
Expand Down Expand Up @@ -69,3 +69,59 @@ where
let (arch, path) = query_space_view_sub_archetype(space_view_id, blueprint_db, query);
(arch.ok().flatten().unwrap_or_default(), path)
}

/// Read a single component of a blueprint archetype in a space view.
pub fn get_blueprint_component<A: re_types::Archetype, C: re_types::Component>(
ctx: &ViewerContext<'_>,
space_view_id: SpaceViewId,
) -> Option<C> {
let blueprint_db = ctx.store_context.blueprint;
let query = ctx.blueprint_query;
let path = entity_path_for_space_view_sub_archetype::<A>(space_view_id, blueprint_db.tree());
blueprint_db
.latest_at_component::<C>(&path, query)
.map(|x| x.value)
}

/// Edit a single component of a blueprint archetype in a space view.
///
/// Set to `None` to reset the value to the value in the default blueprint, if any,
/// else will just store `None` (an empty component list) in the store.
pub fn edit_blueprint_component<A: re_types::Archetype, C: re_types::Component + PartialEq, R>(
ctx: &ViewerContext<'_>,
space_view_id: SpaceViewId,
edit_component: impl FnOnce(&mut Option<C>) -> R,
) -> R {
let active_blueprint = ctx.store_context.blueprint;
let active_path =
entity_path_for_space_view_sub_archetype::<A>(space_view_id, active_blueprint.tree());
let original_value: Option<C> = active_blueprint
.latest_at_component::<C>(&active_path, ctx.blueprint_query)
.map(|x| x.value);

let mut edited_value = original_value.clone();
let ret = edit_component(&mut edited_value);

if edited_value != original_value {
if let Some(edited) = edited_value {
ctx.save_blueprint_component(&active_path, &edited);
} else {
// Reset to the value in the default blueprint, if any.
let default_value = ctx
.store_context
.default_blueprint
.and_then(|default_blueprint| {
let default_path = entity_path_for_space_view_sub_archetype::<A>(
space_view_id,
default_blueprint.tree(),
);
default_blueprint
.latest_at_component::<C>(&default_path, ctx.blueprint_query)
.map(|x| x.value)
});
ctx.save_blueprint_component(&active_path, &default_value);
}
}

ret
}