Rust 3D可视化与数据分析插件库re_viewer的使用,实现高效实时渲染与交互式数据探索
Rust 3D可视化与数据分析插件库re_viewer的使用,实现高效实时渲染与交互式数据探索
The Rerun Viewer
这是rerun
系列crate中的一部分。
这是包含所有GUI功能的主crate。
可以通过构建Wasm将其编译为Web应用程序。要原生运行它,请使用rerun
二进制文件。
通过gRPC与服务器通信(使用re_grpc_client
)。
安装
在项目目录中运行以下Cargo命令:
cargo add re_viewer
或者将以下行添加到您的Cargo.toml中:
re_viewer = "0.24.1"
完整示例demo
以下是一个使用re_viewer进行3D可视化和数据分析的完整示例:
use re_viewer::ViewerApp;
use rerun::{
components::{ColorRGBA, Point3D, Radius},
demo_util::grid,
external::glam,
MsgSender, RecordingStream,
};
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 创建记录流
let (rec_stream, storage) = RecordingStream::new("demo_stream", None);
// 生成3D网格点
let points = grid(glam::Vec3::splat(-10.0), glam::Vec3::splat(10.0), 10)
.map(Point3D::from)
.collect::<Vec<_>>();
// 设置点的颜色和半径
let colors = vec![ColorRGBA::from_rgb(255, 0, 0); points.len()];
let radii = vec![Radius(0.5); points.len()];
// 发送数据到viewer
MsgSender::new("grid")
.with_component(&points)?
.with_component(&colors)?
.with_component(&radii)?
.send(&rec_stream)?;
// 运行viewer应用
ViewerApp::with_storage(storage)?.run()?;
Ok(())
}
示例说明
- 首先创建了一个记录流(
RecordingStream
)用于数据传输 - 使用
grid
函数生成了一个3D网格点阵 - 为所有点设置了红色和半径0.5的属性
- 使用
MsgSender
将数据发送到viewer - 最后启动
ViewerApp
显示数据
这个示例展示了如何:
- 创建3D点云数据
- 设置可视化属性(颜色、大小)
- 将数据传输到viewer
- 启动交互式3D可视化界面
主要功能
re_viewer提供了以下核心功能:
- 高效的3D实时渲染
- 交互式数据探索
- 支持多种数据类型(点云、网格、图像等)
- 跨平台支持(原生和Web)
- 可扩展的插件架构
许可证
re_viewer采用双重许可:
- MIT许可证
- Apache-2.0许可证
1 回复
Rust 3D可视化与数据分析插件库re_viewer使用指南
概述
re_viewer是Rust生态中一个强大的3D可视化与数据分析工具库,专注于实现高效实时渲染和交互式数据探索。它特别适合需要处理大规模数据集并进行3D可视化的应用场景。
主要特性
- 高性能3D渲染引擎
- 实时数据更新与可视化
- 交互式数据探索界面
- 支持多种数据类型和格式
- 跨平台兼容性
安装方法
在Cargo.toml中添加依赖:
[dependencies]
re_viewer = "0.8" # 请使用最新版本
基本使用方法
1. 初始化查看器
use re_viewer::Viewer;
fn main() {
let viewer = Viewer::new("My 3D Viewer");
viewer.run();
}
2. 添加3D点云数据
use re_viewer::{Viewer, PointCloudBuilder};
use nalgebra::Point3;
fn main() {
let mut viewer = Viewer::new("Point Cloud Example");
// 创建点云数据
let points = vec![
Point3::new(0.0, 0.0, 0.0),
Point3::new(1.0, 0.0, 0.0),
Point3::new(0.0, 1.0, 0.0),
Point3::new(0.0, 0.0, 1.0),
];
// 构建点云并添加到查看器
let point_cloud = PointCloudBuilder::new(points)
.with_color([1.0, 0.0, 0.0, 1.0]) // RGBA
.with_point_size(5.0)
.build();
viewer.add_geometry("my_points", point_cloud);
viewer.run();
}
3. 实时数据更新
use re_viewer::{Viewer, TimeSeriesBuilder};
use std::time::{Duration, Instant};
fn main() {
let mut viewer = Viewer::new("Real-time Data Example");
// 创建时间序列数据
let mut series = TimeSeriesBuilder::new("sensor_data");
let start_time = Instant::now();
// 模拟实时数据更新
viewer.set_update_callback(move |viewer| {
let elapsed = start_time.elapsed().as_secs_f32();
let value = elapsed.sin(); // 生成正弦波数据
series.add_point(elapsed, value);
// 更新可视化
viewer.add_time_series("sensor", series.clone());
// 控制更新频率
std::thread::sleep(Duration::from_millis(16)); // ~60fps
});
viewer.run();
}
高级功能
1. 交互式数据探索
use re_viewer::{Viewer, MeshBuilder};
use re_viewer::interaction::{SelectionCallback, Selection};
fn main() {
let mut viewer = Viewer::new("Interactive Exploration");
// 创建一个简单的网格
let mesh = MeshBuilder::new()
.add_triangle([0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0])
.with_color([0.0, 0.5, 1.0, 1.0])
.build();
viewer.add_geometry("triangle", mesh);
// 设置选择回调
viewer.set_selection_callback(|selection| {
match selection {
Selection::Geometry { name, .. } => {
println!("Selected geometry: {}", name);
}
Selection::Point { position, .. } => {
println!("Selected point at: {:?}", position);
}
_ => {}
}
});
viewer.run();
}
2. 多视图布局
use re_viewer::{Viewer, ViewportLayout};
fn main() {
let mut viewer = Viewer::new("Multi-view Layout");
// 定义视图布局
let layout = ViewportLayout::new()
.add_view("Top View", |v| v.set_view_2d_top())
.add_view("Front View", |v| v.set_view_2d_front())
.add_view("3D View", |v| v.set_view_3d());
viewer.set_viewport_layout(layout);
// 添加一些示例数据
// ...
viewer.run();
}
性能优化技巧
- 数据批处理:将相似的数据合并为单个批次减少绘制调用
- LOD(细节层次):为大型数据集实现不同细节级别的渲染
- 异步加载:对大型数据集使用后台线程加载
- 实例化渲染:对重复几何体使用实例化渲染
// 实例化渲染示例
use re_viewer::{Viewer, InstancedMeshBuilder};
fn instanced_rendering_example() {
let mut viewer = Viewer::new("Instanced Rendering");
let base_mesh = // ... 创建基础网格
let positions = vec![
[0.0, 0.0, 0.0],
[1.0, 0.0, 0.0],
[0.0, 1.0, 0.0],
// ... 更多实例位置
];
let instanced_mesh = InstancedMeshBuilder::new(base_mesh)
.with_positions(positions)
.build();
viewer.add_geometry("instanced_objects", instanced_mesh);
viewer.run();
}
实际应用场景
- 科学数据可视化
- 工程仿真结果分析
- 地理空间数据探索
- 金融时间序列分析
- 机器学习模型可视化
re_viewer提供了强大的工具集,可以帮助开发者快速构建高性能的3D数据可视化应用,特别适合需要实时交互和大规模数据渲染的场景。
完整示例代码
// 完整3D数据可视化示例
use re_viewer::{Viewer, PointCloudBuilder, MeshBuilder, TimeSeriesBuilder};
use re_viewer::interaction::{SelectionCallback, Selection};
use nalgebra::Point3;
use std::time::{Duration, Instant};
fn main() {
// 初始化查看器
let mut viewer = Viewer::new("Complete 3D Visualization Example");
// 1. 添加点云数据
let points = vec![
Point3::new(0.0, 0.0, 0.0),
Point3::new(1.0, 0.0, 0.0),
Point3::new(0.0, 1.0, 0.0),
Point3::new(0.0, 0.0, 1.0),
];
let point_cloud = PointCloudBuilder::new(points)
.with_color([1.0, 0.0, 0.0, 1.0])
.with_point_size(5.0)
.build();
viewer.add_geometry("points", point_cloud);
// 2. 添加网格数据
let mesh = MeshBuilder::new()
.add_triangle([0.5, 0.5, 0.5], [1.5, 0.5, 0.5], [0.5, 1.5, 0.5])
.with_color([0.0, 0.5, 1.0, 1.0])
.build();
viewer.add_geometry("triangle", mesh);
// 3. 设置交互回调
viewer.set_selection_callback(|selection| {
match selection {
Selection::Geometry { name, .. } => {
println!("选中几何体: {}", name);
}
Selection::Point { position, .. } => {
println!("选中点位置: {:?}", position);
}
_ => {}
}
});
// 4. 实时数据更新
let mut series = TimeSeriesBuilder::new("sensor");
let start_time = Instant::now();
viewer.set_update_callback(move |viewer| {
let elapsed = start_time.elapsed().as_secs_f32();
let value = elapsed.sin();
series.add_point(elapsed, value);
viewer.add_time_series("sensor", series.clone());
std::thread::sleep(Duration::from_millis(16));
});
// 5. 设置多视图布局
let layout = re_viewer::ViewportLayout::new()
.add_view("Top", |v| v.set_view_2d_top())
.add_view("3D", |v| v.set_view_3d());
viewer.set_viewport_layout(layout);
// 运行查看器
viewer.run();
}