use re_log_types::{TimeInt, Timeline};
use re_space_view::{AnnotationSceneContext, DataResultQuery as _, HybridResults};
use re_types::Archetype;
use re_viewer_context::{
IdentifiedViewSystem, QueryContext, SpaceViewSystemExecutionError, ViewContext,
ViewContextCollection, ViewQuery,
};
use crate::contexts::{EntityDepthOffsets, SpatialSceneEntityContext, TransformContext};
#[inline]
pub fn clamped_or<'a, T>(values: &'a [T], if_empty: &'a T) -> impl Iterator<Item = &'a T> + Clone {
let repeated = values.last().unwrap_or(if_empty);
values.iter().chain(std::iter::repeat(repeated))
}
#[inline]
pub fn clamped_vec_or_empty<T: Clone>(values: &[T], clamped_len: usize) -> Vec<T> {
if values.len() == clamped_len {
values.to_vec() } else if let Some(last) = values.last() {
if values.len() == 1 {
return vec![last.clone(); clamped_len];
} else if values.len() < clamped_len {
let mut vec = Vec::with_capacity(clamped_len);
vec.extend(values.iter().cloned());
vec.extend(std::iter::repeat(last.clone()).take(clamped_len - values.len()));
vec
} else {
values.iter().take(clamped_len).cloned().collect()
}
} else {
Vec::new()
}
}
#[test]
fn test_clamped_vec() {
assert_eq!(clamped_vec_or_empty::<i32>(&[], 0), Vec::<i32>::default());
assert_eq!(clamped_vec_or_empty::<i32>(&[], 3), Vec::<i32>::default());
assert_eq!(
clamped_vec_or_empty::<i32>(&[1, 2, 3], 0),
Vec::<i32>::default()
);
assert_eq!(clamped_vec_or_empty::<i32>(&[1, 2, 3], 1), vec![1]);
assert_eq!(clamped_vec_or_empty::<i32>(&[1, 2, 3], 2), vec![1, 2]);
assert_eq!(clamped_vec_or_empty::<i32>(&[1, 2, 3], 3), vec![1, 2, 3]);
assert_eq!(
clamped_vec_or_empty::<i32>(&[1, 2, 3], 5),
vec![1, 2, 3, 3, 3]
);
}
pub fn process_archetype<System: IdentifiedViewSystem, A, F>(
ctx: &ViewContext<'_>,
query: &ViewQuery<'_>,
view_ctx: &ViewContextCollection,
mut fun: F,
) -> Result<(), SpaceViewSystemExecutionError>
where
A: Archetype,
F: FnMut(
&QueryContext<'_>,
&SpatialSceneEntityContext<'_>,
&HybridResults<'_>,
) -> Result<(), SpaceViewSystemExecutionError>,
{
let transforms = view_ctx.get::<TransformContext>()?;
let depth_offsets = view_ctx.get::<EntityDepthOffsets>()?;
let annotations = view_ctx.get::<AnnotationSceneContext>()?;
let latest_at = query.latest_at_query();
let system_identifier = System::identifier();
for data_result in query.iter_visible_data_results(ctx, system_identifier) {
let Some(transform_info) = transforms.transform_info_for_entity(&data_result.entity_path)
else {
continue;
};
let depth_offset_key = (system_identifier, data_result.entity_path.hash());
let entity_context = SpatialSceneEntityContext {
transform_info,
depth_offset: depth_offsets
.per_entity_and_visualizer
.get(&depth_offset_key)
.copied()
.unwrap_or_default(),
annotations: annotations.0.find(&data_result.entity_path),
highlight: query
.highlights
.entity_outline_mask(data_result.entity_path.hash()),
space_view_class_identifier: view_ctx.space_view_class_identifier(),
};
let results = data_result.query_archetype_with_history::<A>(ctx, query);
let mut query_ctx = ctx.query_context(data_result, &latest_at);
query_ctx.archetype_name = Some(A::name());
{
re_tracing::profile_scope!(format!("{}", data_result.entity_path));
fun(&query_ctx, &entity_context, &results)?;
}
}
Ok(())
}
use re_chunk::{Chunk, ChunkComponentIterItem, ComponentName, RowId};
use re_chunk_store::external::{re_chunk, re_chunk::external::arrow2};
#[allow(unused)]
pub fn iter_component<'a, C: re_types::Component>(
chunks: &'a std::borrow::Cow<'a, [Chunk]>,
timeline: Timeline,
component_name: ComponentName,
) -> impl Iterator<Item = ((TimeInt, RowId), ChunkComponentIterItem<C>)> + 'a {
chunks.iter().flat_map(move |chunk| {
itertools::izip!(
chunk.iter_component_indices(&timeline, &component_name),
chunk.iter_component::<C>()
)
})
}
#[allow(unused)]
pub fn iter_primitive<'a, T: arrow2::types::NativeType>(
chunks: &'a std::borrow::Cow<'a, [Chunk]>,
timeline: Timeline,
component_name: ComponentName,
) -> impl Iterator<Item = ((TimeInt, RowId), &'a [T])> + 'a {
chunks.iter().flat_map(move |chunk| {
itertools::izip!(
chunk.iter_component_indices(&timeline, &component_name),
chunk.iter_primitive::<T>(&component_name)
)
})
}
#[allow(unused)]
pub fn iter_primitive_array<'a, const N: usize, T: arrow2::types::NativeType>(
chunks: &'a std::borrow::Cow<'a, [Chunk]>,
timeline: Timeline,
component_name: ComponentName,
) -> impl Iterator<Item = ((TimeInt, RowId), &'a [[T; N]])> + 'a
where
[T; N]: bytemuck::Pod,
{
chunks.iter().flat_map(move |chunk| {
itertools::izip!(
chunk.iter_component_indices(&timeline, &component_name),
chunk.iter_primitive_array::<N, T>(&component_name)
)
})
}
#[allow(unused)]
pub fn iter_primitive_array_list<'a, const N: usize, T: arrow2::types::NativeType>(
chunks: &'a std::borrow::Cow<'a, [Chunk]>,
timeline: Timeline,
component_name: ComponentName,
) -> impl Iterator<Item = ((TimeInt, RowId), Vec<&'a [[T; N]]>)> + 'a
where
[T; N]: bytemuck::Pod,
{
chunks.iter().flat_map(move |chunk| {
itertools::izip!(
chunk.iter_component_indices(&timeline, &component_name),
chunk.iter_primitive_array_list::<N, T>(&component_name)
)
})
}
#[allow(unused)]
pub fn iter_string<'a>(
chunks: &'a std::borrow::Cow<'a, [Chunk]>,
timeline: Timeline,
component_name: ComponentName,
) -> impl Iterator<Item = ((TimeInt, RowId), Vec<re_types::ArrowString>)> + 'a {
chunks.iter().flat_map(move |chunk| {
itertools::izip!(
chunk.iter_component_indices(&timeline, &component_name),
chunk.iter_string(&component_name)
)
})
}
#[allow(unused)]
pub fn iter_buffer<'a, T: arrow2::types::NativeType>(
chunks: &'a std::borrow::Cow<'a, [Chunk]>,
timeline: Timeline,
component_name: ComponentName,
) -> impl Iterator<Item = ((TimeInt, RowId), Vec<re_types::ArrowBuffer<T>>)> + 'a {
chunks.iter().flat_map(move |chunk| {
itertools::izip!(
chunk.iter_component_indices(&timeline, &component_name),
chunk.iter_buffer(&component_name)
)
})
}