Skip to content

Commit

Permalink
Added Rust version of the "Loggable Data Types" doc section (#2501)
Browse files Browse the repository at this point in the history
### What

This PR introduces Rust versions of the "Loggable Data Types"
documentation section.

Choices I made along the way:
- The primary aim was to stick as much as possible to the Python
versions. The output should be the same.
- I've used `ndarray` for all example (as opposed to, e.g.,
`ImageBuffer` for image-related examples).
- I skipped translating `image_advanced.py` as it primarily focuses
various Python packages (Pillow, OpenCV).

### Checklist
* [x] I have read and agree to [Contributor
Guide](https://github.com/rerun-io/rerun/blob/main/CONTRIBUTING.md) and
the [Code of
Conduct](https://github.com/rerun-io/rerun/blob/main/CODE_OF_CONDUCT.md)
* [ ] I've included a screenshot or gif (if applicable)

<!-- This line will get updated when the PR build summary job finishes.
-->
PR Build Summary: https://build.rerun.io/pr/2501

<!-- pr-link-docs:start -->
Docs preview: https://rerun.io/preview/72885f5/docs
Examples preview: https://rerun.io/preview/72885f5/examples
<!-- pr-link-docs:end -->

---------

Co-authored-by: Clement Rey <cr.rey.clement@gmail.com>
  • Loading branch information
abey79 and teh-cmc authored Jun 27, 2023
1 parent 1b10c67 commit b6fdc00
Show file tree
Hide file tree
Showing 26 changed files with 920 additions and 7 deletions.
6 changes: 5 additions & 1 deletion Cargo.lock

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

114 changes: 108 additions & 6 deletions docs/code-examples/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,14 +1,116 @@
[package]
name = "code_examples"
version = "0.7.0-alpha.0"
edition = "2021"
rust-version = "1.69"
license = "MIT OR Apache-2.0"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
publish = false


[[bin]]
name = "annotation_context_connections"
path = "annotation_context_connections.rs"

[[bin]]
name = "annotation_context_rects"
path = "annotation_context_rects.rs"

[[bin]]
name = "annotation_context_segmentation"
path = "annotation_context_segmentation.rs"

[[bin]]
name = "arrow3d_simple"
path = "arrow3d_simple.rs"

[[bin]]
name = "box3d_simple"
path = "box3d_simple.rs"

[[bin]]
name = "depth_image_3d"
path = "depth_image_3d.rs"

[[bin]]
name = "depth_image_simple"
path = "depth_image_simple.rs"

[[bin]]
name = "image_simple"
path = "image_simple.rs"

[[bin]]
name = "line_segments2d_simple"
path = "line_segments2d_simple.rs"

[[bin]]
name = "line_segments3d_simple"
path = "line_segments3d_simple.rs"

[[bin]]
name = "line_strip2d_simple"
path = "line_strip2d_simple.rs"

[[bin]]
name = "line_strip3d_simple"
path = "line_strip3d_simple.rs"

[[bin]]
name = 'point2d_simple'
path = 'point2d_simple.rs'
name = "mesh_simple"
path = "mesh_simple.rs"

[[bin]]
name = "pinhole_simple"
path = "pinhole_simple.rs"

[[bin]]
name = "point2d_simple"
path = "point2d_simple.rs"

[[bin]]
name = "point2d_random"
path = "point2d_random.rs"

[[bin]]
name = "point3d_random"
path = "point3d_random.rs"

[[bin]]
name = "point3d_simple"
path = "point3d_simple.rs"

[[bin]]
name = "rect2d_simple"
path = "rect2d_simple.rs"

[[bin]]
name = "scalar_simple"
path = "scalar_simple.rs"

[[bin]]
name = "segmentation_image_simple"
path = "segmentation_image_simple.rs"

[[bin]]
name = "tensor_one_dim"
path = "tensor_one_dim.rs"

[[bin]]
name = "tensor_simple"
path = "tensor_simple.rs"

[[bin]]
name = "text_entry_simple"
path = "text_entry_simple.rs"

[[bin]]
name = "transform3d_simple"
path = "transform3d_simple.rs"


[dependencies]
ahash.workspace = true
ndarray.workspace = true
rand.workspace = true
rand_distr.workspace = true
rerun = { path = "../../crates/rerun", features = ["native_viewer"] }
82 changes: 82 additions & 0 deletions docs/code-examples/annotation_context_connections.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
//! Log some very simple points.
use rerun::components::{
AnnotationContext, AnnotationInfo, ClassDescription, ClassId, ColorRGBA, KeypointId, Label,
Point3D,
};
use rerun::{MsgSender, RecordingStreamBuilder};

fn main() -> Result<(), Box<dyn std::error::Error>> {
let (rec_stream, storage) =
RecordingStreamBuilder::new("annotation_context_connections").memory()?;

// Log an annotation context to assign a label and color to each class
// Create a class description with labels and color for each keypoint ID as well as some
// connections between keypoints.
let mut class_desc = ClassDescription::default();
class_desc.keypoint_map.insert(
KeypointId(0),
AnnotationInfo {
id: 0,
label: Some(Label("zero".to_owned())),
color: Some(ColorRGBA::from_rgb(255, 0, 0)),
},
);
class_desc.keypoint_map.insert(
KeypointId(1),
AnnotationInfo {
id: 1,
label: Some(Label("one".to_owned())),
color: Some(ColorRGBA::from_rgb(0, 255, 0)),
},
);
class_desc.keypoint_map.insert(
KeypointId(2),
AnnotationInfo {
id: 2,
label: Some(Label("two".to_owned())),
color: Some(ColorRGBA::from_rgb(0, 0, 255)),
},
);
class_desc.keypoint_map.insert(
KeypointId(3),
AnnotationInfo {
id: 3,
label: Some(Label("three".to_owned())),
color: Some(ColorRGBA::from_rgb(255, 255, 0)),
},
);
class_desc.keypoint_connections = [(0, 2), (1, 2), (2, 3)]
.into_iter()
.map(|(a, b)| (KeypointId(a), KeypointId(b)))
.collect();

let mut annotation = AnnotationContext::default();
annotation.class_map.insert(ClassId(0), class_desc);

MsgSender::new("/")
.with_component(&[annotation])?
.send(&rec_stream)?;

// Log some points with different keypoint IDs
let points = [
[0., 0., 0.],
[50., 0., 20.],
[100., 100., 30.],
[0., 50., 40.],
]
.into_iter()
.map(Point3D::from)
.collect::<Vec<_>>();

MsgSender::new("points")
.with_component(&points)?
.with_component(&[KeypointId(0), KeypointId(1), KeypointId(2), KeypointId(3)])?
.with_splat(ClassId(0))?
.send(&rec_stream)?;

rec_stream.flush_blocking();

rerun::native_viewer::show(storage.take())?;

Ok(())
}
56 changes: 56 additions & 0 deletions docs/code-examples/annotation_context_rects.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
//! Log rectangles with different colors and labels.
use rerun::components::{
AnnotationContext, AnnotationInfo, ClassDescription, ClassId, ColorRGBA, Label, Rect2D, Vec4D,
};
use rerun::{MsgSender, RecordingStreamBuilder};

fn main() -> Result<(), Box<dyn std::error::Error>> {
let (rec_stream, storage) = RecordingStreamBuilder::new("annotation_context_rects").memory()?;

// Log an annotation context to assign a label and color to each class
let mut annotation = AnnotationContext::default();
annotation.class_map.insert(
ClassId(1),
ClassDescription {
info: AnnotationInfo {
id: 1,
label: Some(Label("red".to_owned())),
color: Some(ColorRGBA::from_rgb(255, 0, 0)),
},
..Default::default()
},
);
annotation.class_map.insert(
ClassId(2),
ClassDescription {
info: AnnotationInfo {
id: 2,
label: Some(Label("green".to_owned())),
color: Some(ColorRGBA::from_rgb(0, 255, 0)),
},
..Default::default()
},
);

MsgSender::new("/")
.with_component(&[annotation])?
.send(&rec_stream)?;

// Log a batch of 2 rectangles with different class IDs
MsgSender::new("detections")
.with_component(&[
Rect2D::XYWH(Vec4D([-2., -2., 3., 3.])),
Rect2D::XYWH(Vec4D([0., 0., 2., 2.])),
])?
.with_component(&[ClassId(1), ClassId(2)])?
.send(&rec_stream)?;

// Log an extra rect to set the view bounds
MsgSender::new("bounds")
.with_component(&[Rect2D::XCYCWH(Vec4D([0.0, 0.0, 5.0, 5.0]))])?
.send(&rec_stream)?;

rec_stream.flush_blocking();
rerun::native_viewer::show(storage.take())?;
Ok(())
}
58 changes: 58 additions & 0 deletions docs/code-examples/annotation_context_segmentation.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
//! Log a segmentation image with annotations.
use ndarray::{s, Array, ShapeBuilder};
use rerun::components::{
AnnotationContext, AnnotationInfo, ClassDescription, ClassId, ColorRGBA, Label, Tensor,
TensorDataMeaning,
};
use rerun::{MsgSender, RecordingStreamBuilder};

fn main() -> Result<(), Box<dyn std::error::Error>> {
let (rec_stream, storage) =
RecordingStreamBuilder::new("annotation_context_segmentation").memory()?;

// create a segmentation image
let mut data = Array::<u8, _>::zeros((200, 300).f());
data.slice_mut(s![50..150, 50..120]).fill(1);
data.slice_mut(s![100..180, 130..280]).fill(2);

let mut image = Tensor::try_from(data.as_standard_layout().view())?;
image.meaning = TensorDataMeaning::ClassId;

// create an annotation context to describe the classes
let mut annotation = AnnotationContext::default();
annotation.class_map.insert(
ClassId(1),
ClassDescription {
info: AnnotationInfo {
id: 1,
label: Some(Label("red".to_owned())),
color: Some(ColorRGBA::from_rgb(255, 0, 0)),
},
..Default::default()
},
);
annotation.class_map.insert(
ClassId(2),
ClassDescription {
info: AnnotationInfo {
id: 2,
label: Some(Label("green".to_owned())),
color: Some(ColorRGBA::from_rgb(0, 255, 0)),
},
..Default::default()
},
);

// log the annotation and the image
MsgSender::new("segmentation")
.with_component(&[annotation])?
.send(&rec_stream)?;

MsgSender::new("segmentation/image")
.with_component(&[image])?
.send(&rec_stream)?;

rec_stream.flush_blocking();
rerun::native_viewer::show(storage.take())?;
Ok(())
}
21 changes: 21 additions & 0 deletions docs/code-examples/arrow3d_simple.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//! Log a single arrow
use rerun::components::{Arrow3D, Radius, Vec3D};
use rerun::{MsgSender, RecordingStreamBuilder};

fn main() -> Result<(), Box<dyn std::error::Error>> {
let (rec_stream, storage) = RecordingStreamBuilder::new("arrow").memory()?;

let arrow = Arrow3D {
origin: Vec3D::from([0.0, 0.0, 0.0]),
vector: Vec3D::from([1.0, 0.0, 1.0]),
};

MsgSender::new("arrow")
.with_component(&[arrow])?
.with_component(&[Radius(0.05)])?
.send(&rec_stream)?;

rec_stream.flush_blocking();
rerun::native_viewer::show(storage.take())?;
Ok(())
}
15 changes: 15 additions & 0 deletions docs/code-examples/box3d_simple.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//! Log some a single oriented bounding box
use rerun::components::Box3D;
use rerun::{MsgSender, RecordingStreamBuilder};

fn main() -> Result<(), Box<dyn std::error::Error>> {
let (rec_stream, storage) = RecordingStreamBuilder::new("box3d").memory()?;

MsgSender::new("simple")
.with_component(&[Box3D::new(2.0, 2.0, 1.0)])?
.send(&rec_stream)?;

rec_stream.flush_blocking();
rerun::native_viewer::show(storage.take())?;
Ok(())
}
Loading

0 comments on commit b6fdc00

Please sign in to comment.