use re_log_types::EntityPath;
use re_sdk_types::ViewClassIdentifier;
use re_sdk_types::blueprint::components::VisualizerInstructionId;
use re_viewer_context::{ViewClass as _, VisualizerExecutionOutput, VisualizerReportSeverity};
use crate::contexts::{TransformInfo, TransformTreeContext};
use crate::view_kind::SpatialViewKind;
pub fn spatial_view_kind_from_view_class(class: ViewClassIdentifier) -> SpatialViewKind {
if class == crate::SpatialView3D::identifier() {
SpatialViewKind::ThreeD
} else if class == crate::SpatialView2D::identifier() {
SpatialViewKind::TwoD
} else {
re_log::debug_panic!("Not a spatial view class identifier {class:?}");
SpatialViewKind::TwoD
}
}
pub fn transform_info_for_archetype_or_report_error<'a>(
entity_path: &EntityPath,
transform_context: &'a TransformTreeContext,
archetype_kind: Option<SpatialViewKind>,
view_kind: SpatialViewKind,
instruction_id: &VisualizerInstructionId,
output: &VisualizerExecutionOutput,
) -> Option<&'a TransformInfo> {
re_tracing::profile_function!();
let result = transform_context.target_from_entity_path(entity_path.hash());
let transform_info = match format_transform_info_result(entity_path, transform_context, result)
{
Ok(transform_info) => transform_info,
Err(err_msg) => {
output.report_unspecified_source(
*instruction_id,
VisualizerReportSeverity::Error,
err_msg,
);
return None;
}
};
is_valid_space_for_content(
entity_path,
instruction_id,
transform_context,
transform_info,
archetype_kind,
view_kind,
output,
)
.then_some(transform_info)
}
pub fn format_transform_info_result<'a>(
entity_path: &EntityPath,
transform_context: &TransformTreeContext,
result: Option<&'a Result<TransformInfo, re_tf::TransformFromToError>>,
) -> Result<&'a TransformInfo, String> {
match result {
None => {
if transform_context
.is_empty_frame_name(transform_context.transform_frame_id_for(entity_path.hash()))
{
Err(
"Transform relation can't be resolved due to empty coordinate frame name."
.to_owned(),
)
} else {
Err("No transform relation known for this entity.".to_owned())
}
}
Some(Err(re_tf::TransformFromToError::NoPathBetweenFrames { src, target, .. })) => {
let src = if let Some(frame_id) =
transform_context.format_frame_or_debug_warn(*src, entity_path)
{
format!("{frame_id:?}")
} else {
format!("{entity_path}:?")
};
let target = if let Some(target) =
transform_context.format_frame_or_debug_warn(*target, entity_path)
{
format!(" ({target:?})")
} else {
String::new()
};
Err(format!(
"No transform path from {src} to the view's target frame{target}."
))
}
Some(Err(re_tf::TransformFromToError::UnknownTargetFrame(target))) => {
if transform_context
.lookup_frame_id(*target)
.is_some_and(|frame_id| frame_id.as_str().is_empty())
{
return Err(
"View target frame can't be resolved due to empty coordinate frame name."
.to_owned(),
);
}
let target = if let Some(target) =
transform_context.format_frame_or_debug_warn(*target, entity_path)
{
format!("target frame {target:?}")
} else {
"target frame".to_owned()
};
Err(format!("The view's {target} is unknown."))
}
Some(Err(re_tf::TransformFromToError::UnknownSourceFrame(src))) => {
if transform_context.is_empty_frame_name(*src) {
return Err(
"Transform relation can't be resolved due to empty coordinate frame name."
.to_owned(),
);
}
let src = if let Some(frame_id) =
transform_context.format_frame_or_debug_warn(*src, entity_path)
{
format!("{frame_id:?}")
} else {
format!("{entity_path:?}")
};
Err(format!("The entity's coordinate frame {src} is unknown."))
}
Some(Ok(transform_info)) => Ok(transform_info),
}
}
pub fn is_valid_space_for_content(
entity_path: &EntityPath,
instruction_id: &VisualizerInstructionId,
transform_context: &TransformTreeContext,
transform: &TransformInfo,
content_kind: Option<SpatialViewKind>,
view_kind: SpatialViewKind,
output: &VisualizerExecutionOutput,
) -> bool {
let Some(content_view_kind) = content_kind else {
return true;
};
let target_frame_pinhole_root = transform_context.target_frame_pinhole_root();
if view_kind == SpatialViewKind::ThreeD
&& let Some(target_frame_pinhole_root) = target_frame_pinhole_root
{
let origin = if let Some(origin) =
transform_context.format_frame_or_debug_warn(target_frame_pinhole_root, entity_path)
{
format!("The origin of the 3D view ({origin:?})")
} else {
"The origin of the 3D view".to_owned()
};
output.report_unspecified_source(*instruction_id, VisualizerReportSeverity::Error, format!(
"{origin} is under pinhole projection which is not supported by most 3D visualizations."
));
return false;
}
let transform_has_pinhole_ancestor = transform_context
.pinhole_tree_root_info(transform.tree_root())
.is_some();
match content_view_kind {
SpatialViewKind::TwoD => {
match view_kind {
SpatialViewKind::TwoD => {
if transform_has_pinhole_ancestor
&& target_frame_pinhole_root.is_none_or(|target_frame_pinhole_root| {
target_frame_pinhole_root != transform.tree_root()
})
{
output.report_unspecified_source(
*instruction_id,
VisualizerReportSeverity::Error,
"Can't visualize 2D content with a pinhole ancestor that's embedded within the 2D view. This applies a 3D → 2D projection to a space that's already regarded 2D.",
);
false
} else {
true
}
}
SpatialViewKind::ThreeD => {
if transform_has_pinhole_ancestor {
true
} else {
output.report_unspecified_source(
*instruction_id,
VisualizerReportSeverity::Error,
"2D visualizers require a pinhole ancestor to be shown in a 3D view.",
);
false
}
}
}
}
SpatialViewKind::ThreeD => {
if transform_has_pinhole_ancestor {
output.report_unspecified_source(
*instruction_id,
VisualizerReportSeverity::Error,
"Can't visualize 3D content that is under a pinhole projection.",
);
return false;
}
match view_kind {
SpatialViewKind::TwoD => {
if target_frame_pinhole_root == Some(transform_context.target_frame()) {
true
} else {
output.report_unspecified_source(
*instruction_id,
VisualizerReportSeverity::Error,
"3D visualizers require a pinhole at the origin of the 2D view.",
);
false
}
}
SpatialViewKind::ThreeD => true, }
}
}
}