re_types/archetypes/points3d.rs
1// DO NOT EDIT! This file was auto-generated by crates/build/re_types_builder/src/codegen/rust/api.rs
2// Based on "crates/store/re_types/definitions/rerun/archetypes/points3d.fbs".
3
4#![allow(unused_braces)]
5#![allow(unused_imports)]
6#![allow(unused_parens)]
7#![allow(clippy::allow_attributes)]
8#![allow(clippy::clone_on_copy)]
9#![allow(clippy::cloned_instead_of_copied)]
10#![allow(clippy::map_flatten)]
11#![allow(clippy::needless_question_mark)]
12#![allow(clippy::new_without_default)]
13#![allow(clippy::redundant_closure)]
14#![allow(clippy::too_many_arguments)]
15#![allow(clippy::too_many_lines)]
16#![allow(clippy::wildcard_imports)]
17
18use ::re_types_core::SerializationResult;
19use ::re_types_core::try_serialize_field;
20use ::re_types_core::{ComponentBatch as _, SerializedComponentBatch};
21use ::re_types_core::{ComponentDescriptor, ComponentType};
22use ::re_types_core::{DeserializationError, DeserializationResult};
23
24/// **Archetype**: A 3D point cloud with positions and optional colors, radii, labels, etc.
25///
26/// If there are multiple instance poses, the entire point cloud will be repeated for each of the poses.
27///
28/// ## Examples
29///
30/// ### Simple 3D points
31/// ```ignore
32/// fn main() -> Result<(), Box<dyn std::error::Error>> {
33/// let rec = rerun::RecordingStreamBuilder::new("rerun_example_points3d").spawn()?;
34///
35/// rec.log(
36/// "points",
37/// &rerun::Points3D::new([(0.0, 0.0, 0.0), (1.0, 1.0, 1.0)]),
38/// )?;
39///
40/// Ok(())
41/// }
42/// ```
43/// <center>
44/// <picture>
45/// <source media="(max-width: 480px)" srcset="https://static.rerun.io/point3d_simple/32fb3e9b65bea8bd7ffff95ad839f2f8a157a933/480w.png">
46/// <source media="(max-width: 768px)" srcset="https://static.rerun.io/point3d_simple/32fb3e9b65bea8bd7ffff95ad839f2f8a157a933/768w.png">
47/// <source media="(max-width: 1024px)" srcset="https://static.rerun.io/point3d_simple/32fb3e9b65bea8bd7ffff95ad839f2f8a157a933/1024w.png">
48/// <source media="(max-width: 1200px)" srcset="https://static.rerun.io/point3d_simple/32fb3e9b65bea8bd7ffff95ad839f2f8a157a933/1200w.png">
49/// <img src="https://static.rerun.io/point3d_simple/32fb3e9b65bea8bd7ffff95ad839f2f8a157a933/full.png" width="640">
50/// </picture>
51/// </center>
52///
53/// ### Update a point cloud over time
54/// ```ignore
55/// fn main() -> Result<(), Box<dyn std::error::Error>> {
56/// let rec = rerun::RecordingStreamBuilder::new("rerun_example_points3d_row_updates").spawn()?;
57///
58/// // Prepare a point cloud that evolves over 5 timesteps, changing the number of points in the process.
59/// #[rustfmt::skip]
60/// let positions = [
61/// vec![[1.0, 0.0, 1.0], [0.5, 0.5, 2.0]],
62/// vec![[1.5, -0.5, 1.5], [1.0, 1.0, 2.5], [-0.5, 1.5, 1.0], [-1.5, 0.0, 2.0]],
63/// vec![[2.0, 0.0, 2.0], [1.5, -1.5, 3.0], [0.0, -2.0, 2.5], [1.0, -1.0, 3.5]],
64/// vec![[-2.0, 0.0, 2.0], [-1.5, 1.5, 3.0], [-1.0, 1.0, 3.5]],
65/// vec![[1.0, -1.0, 1.0], [2.0, -2.0, 2.0], [3.0, -1.0, 3.0], [2.0, 0.0, 4.0]],
66/// ];
67///
68/// // At each timestep, all points in the cloud share the same but changing color and radius.
69/// let colors = [0xFF0000FF, 0x00FF00FF, 0x0000FFFF, 0xFFFF00FF, 0x00FFFFFF];
70/// let radii = [0.05, 0.01, 0.2, 0.1, 0.3];
71///
72/// for (time, positions, color, radius) in itertools::izip!(10..15, positions, colors, radii) {
73/// rec.set_duration_secs("time", time);
74///
75/// let point_cloud = rerun::Points3D::new(positions)
76/// .with_colors([color])
77/// .with_radii([radius]);
78///
79/// rec.log("points", &point_cloud)?;
80/// }
81///
82/// Ok(())
83/// }
84/// ```
85/// <center>
86/// <picture>
87/// <source media="(max-width: 480px)" srcset="https://static.rerun.io/points3d_row_updates/fba056871b1ec3fc6978ab605d9a63e44ef1f6de/480w.png">
88/// <source media="(max-width: 768px)" srcset="https://static.rerun.io/points3d_row_updates/fba056871b1ec3fc6978ab605d9a63e44ef1f6de/768w.png">
89/// <source media="(max-width: 1024px)" srcset="https://static.rerun.io/points3d_row_updates/fba056871b1ec3fc6978ab605d9a63e44ef1f6de/1024w.png">
90/// <source media="(max-width: 1200px)" srcset="https://static.rerun.io/points3d_row_updates/fba056871b1ec3fc6978ab605d9a63e44ef1f6de/1200w.png">
91/// <img src="https://static.rerun.io/points3d_row_updates/fba056871b1ec3fc6978ab605d9a63e44ef1f6de/full.png" width="640">
92/// </picture>
93/// </center>
94///
95/// ### Update a point cloud over time, in a single operation
96/// ```ignore
97/// fn main() -> Result<(), Box<dyn std::error::Error>> {
98/// let rec =
99/// rerun::RecordingStreamBuilder::new("rerun_example_points3d_column_updates").spawn()?;
100///
101/// let times = rerun::TimeColumn::new_duration_secs("time", 10..15);
102///
103/// // Prepare a point cloud that evolves over 5 timesteps, changing the number of points in the process.
104/// #[rustfmt::skip]
105/// let positions = [
106/// [1.0, 0.0, 1.0], [0.5, 0.5, 2.0],
107/// [1.5, -0.5, 1.5], [1.0, 1.0, 2.5], [-0.5, 1.5, 1.0], [-1.5, 0.0, 2.0],
108/// [2.0, 0.0, 2.0], [1.5, -1.5, 3.0], [0.0, -2.0, 2.5], [1.0, -1.0, 3.5],
109/// [-2.0, 0.0, 2.0], [-1.5, 1.5, 3.0], [-1.0, 1.0, 3.5],
110/// [1.0, -1.0, 1.0], [2.0, -2.0, 2.0], [3.0, -1.0, 3.0], [2.0, 0.0, 4.0],
111/// ];
112///
113/// // At each timestep, all points in the cloud share the same but changing color and radius.
114/// let colors = [0xFF0000FF, 0x00FF00FF, 0x0000FFFF, 0xFFFF00FF, 0x00FFFFFF];
115/// let radii = [0.05, 0.01, 0.2, 0.1, 0.3];
116///
117/// // Partition our data as expected across the 5 timesteps.
118/// let position = rerun::Points3D::update_fields()
119/// .with_positions(positions)
120/// .columns([2, 4, 4, 3, 4])?;
121/// let color_and_radius = rerun::Points3D::update_fields()
122/// .with_colors(colors)
123/// .with_radii(radii)
124/// .columns_of_unit_batches()?;
125///
126/// rec.send_columns("points", [times], position.chain(color_and_radius))?;
127///
128/// Ok(())
129/// }
130/// ```
131/// <center>
132/// <picture>
133/// <source media="(max-width: 480px)" srcset="https://static.rerun.io/points3d_row_updates/fba056871b1ec3fc6978ab605d9a63e44ef1f6de/480w.png">
134/// <source media="(max-width: 768px)" srcset="https://static.rerun.io/points3d_row_updates/fba056871b1ec3fc6978ab605d9a63e44ef1f6de/768w.png">
135/// <source media="(max-width: 1024px)" srcset="https://static.rerun.io/points3d_row_updates/fba056871b1ec3fc6978ab605d9a63e44ef1f6de/1024w.png">
136/// <source media="(max-width: 1200px)" srcset="https://static.rerun.io/points3d_row_updates/fba056871b1ec3fc6978ab605d9a63e44ef1f6de/1200w.png">
137/// <img src="https://static.rerun.io/points3d_row_updates/fba056871b1ec3fc6978ab605d9a63e44ef1f6de/full.png" width="640">
138/// </picture>
139/// </center>
140///
141/// ### Update specific properties of a point cloud over time
142/// ```ignore
143/// fn main() -> Result<(), Box<dyn std::error::Error>> {
144/// let rec =
145/// rerun::RecordingStreamBuilder::new("rerun_example_points3d_partial_updates").spawn()?;
146///
147/// let positions = || (0..10).map(|i| (i as f32, 0.0, 0.0));
148///
149/// rec.set_time_sequence("frame", 0);
150/// rec.log("points", &rerun::Points3D::new(positions()))?;
151///
152/// for i in 0..10 {
153/// let colors = (0..10).map(|n| {
154/// if n < i {
155/// rerun::Color::from_rgb(20, 200, 20)
156/// } else {
157/// rerun::Color::from_rgb(200, 20, 20)
158/// }
159/// });
160/// let radii = (0..10).map(|n| if n < i { 0.6 } else { 0.2 });
161///
162/// // Update only the colors and radii, leaving everything else as-is.
163/// rec.set_time_sequence("frame", i);
164/// rec.log(
165/// "points",
166/// &rerun::Points3D::update_fields()
167/// .with_radii(radii)
168/// .with_colors(colors),
169/// )?;
170/// }
171///
172/// // Update the positions and radii, and clear everything else in the process.
173/// rec.set_time_sequence("frame", 20);
174/// rec.log(
175/// "points",
176/// &rerun::Points3D::clear_fields()
177/// .with_positions(positions())
178/// .with_radii([0.3]),
179/// )?;
180///
181/// Ok(())
182/// }
183/// ```
184/// <center>
185/// <picture>
186/// <source media="(max-width: 480px)" srcset="https://static.rerun.io/points3d_partial_updates/d8bec9c3388d2bd0fe59dff01ab8cde0bdda135e/480w.png">
187/// <source media="(max-width: 768px)" srcset="https://static.rerun.io/points3d_partial_updates/d8bec9c3388d2bd0fe59dff01ab8cde0bdda135e/768w.png">
188/// <source media="(max-width: 1024px)" srcset="https://static.rerun.io/points3d_partial_updates/d8bec9c3388d2bd0fe59dff01ab8cde0bdda135e/1024w.png">
189/// <source media="(max-width: 1200px)" srcset="https://static.rerun.io/points3d_partial_updates/d8bec9c3388d2bd0fe59dff01ab8cde0bdda135e/1200w.png">
190/// <img src="https://static.rerun.io/points3d_partial_updates/d8bec9c3388d2bd0fe59dff01ab8cde0bdda135e/full.png" width="640">
191/// </picture>
192/// </center>
193#[derive(Clone, Debug, PartialEq, Default)]
194pub struct Points3D {
195 /// All the 3D positions at which the point cloud shows points.
196 pub positions: Option<SerializedComponentBatch>,
197
198 /// Optional radii for the points, effectively turning them into circles.
199 pub radii: Option<SerializedComponentBatch>,
200
201 /// Optional colors for the points.
202 pub colors: Option<SerializedComponentBatch>,
203
204 /// Optional text labels for the points.
205 ///
206 /// If there's a single label present, it will be placed at the center of the entity.
207 /// Otherwise, each instance will have its own label.
208 pub labels: Option<SerializedComponentBatch>,
209
210 /// Whether the text labels should be shown.
211 ///
212 /// If not set, labels will automatically appear when there is exactly one label for this entity
213 /// or the number of instances on this entity is under a certain threshold.
214 pub show_labels: Option<SerializedComponentBatch>,
215
216 /// Optional class Ids for the points.
217 ///
218 /// The [`components::ClassId`][crate::components::ClassId] provides colors and labels if not specified explicitly.
219 pub class_ids: Option<SerializedComponentBatch>,
220
221 /// Optional keypoint IDs for the points, identifying them within a class.
222 ///
223 /// If keypoint IDs are passed in but no [`components::ClassId`][crate::components::ClassId]s were specified, the [`components::ClassId`][crate::components::ClassId] will
224 /// default to 0.
225 /// This is useful to identify points within a single classification (which is identified
226 /// with `class_id`).
227 /// E.g. the classification might be 'Person' and the keypoints refer to joints on a
228 /// detected skeleton.
229 pub keypoint_ids: Option<SerializedComponentBatch>,
230}
231
232impl Points3D {
233 /// Returns the [`ComponentDescriptor`] for [`Self::positions`].
234 ///
235 /// The corresponding component is [`crate::components::Position3D`].
236 #[inline]
237 pub fn descriptor_positions() -> ComponentDescriptor {
238 ComponentDescriptor {
239 archetype: Some("rerun.archetypes.Points3D".into()),
240 component: "Points3D:positions".into(),
241 component_type: Some("rerun.components.Position3D".into()),
242 }
243 }
244
245 /// Returns the [`ComponentDescriptor`] for [`Self::radii`].
246 ///
247 /// The corresponding component is [`crate::components::Radius`].
248 #[inline]
249 pub fn descriptor_radii() -> ComponentDescriptor {
250 ComponentDescriptor {
251 archetype: Some("rerun.archetypes.Points3D".into()),
252 component: "Points3D:radii".into(),
253 component_type: Some("rerun.components.Radius".into()),
254 }
255 }
256
257 /// Returns the [`ComponentDescriptor`] for [`Self::colors`].
258 ///
259 /// The corresponding component is [`crate::components::Color`].
260 #[inline]
261 pub fn descriptor_colors() -> ComponentDescriptor {
262 ComponentDescriptor {
263 archetype: Some("rerun.archetypes.Points3D".into()),
264 component: "Points3D:colors".into(),
265 component_type: Some("rerun.components.Color".into()),
266 }
267 }
268
269 /// Returns the [`ComponentDescriptor`] for [`Self::labels`].
270 ///
271 /// The corresponding component is [`crate::components::Text`].
272 #[inline]
273 pub fn descriptor_labels() -> ComponentDescriptor {
274 ComponentDescriptor {
275 archetype: Some("rerun.archetypes.Points3D".into()),
276 component: "Points3D:labels".into(),
277 component_type: Some("rerun.components.Text".into()),
278 }
279 }
280
281 /// Returns the [`ComponentDescriptor`] for [`Self::show_labels`].
282 ///
283 /// The corresponding component is [`crate::components::ShowLabels`].
284 #[inline]
285 pub fn descriptor_show_labels() -> ComponentDescriptor {
286 ComponentDescriptor {
287 archetype: Some("rerun.archetypes.Points3D".into()),
288 component: "Points3D:show_labels".into(),
289 component_type: Some("rerun.components.ShowLabels".into()),
290 }
291 }
292
293 /// Returns the [`ComponentDescriptor`] for [`Self::class_ids`].
294 ///
295 /// The corresponding component is [`crate::components::ClassId`].
296 #[inline]
297 pub fn descriptor_class_ids() -> ComponentDescriptor {
298 ComponentDescriptor {
299 archetype: Some("rerun.archetypes.Points3D".into()),
300 component: "Points3D:class_ids".into(),
301 component_type: Some("rerun.components.ClassId".into()),
302 }
303 }
304
305 /// Returns the [`ComponentDescriptor`] for [`Self::keypoint_ids`].
306 ///
307 /// The corresponding component is [`crate::components::KeypointId`].
308 #[inline]
309 pub fn descriptor_keypoint_ids() -> ComponentDescriptor {
310 ComponentDescriptor {
311 archetype: Some("rerun.archetypes.Points3D".into()),
312 component: "Points3D:keypoint_ids".into(),
313 component_type: Some("rerun.components.KeypointId".into()),
314 }
315 }
316}
317
318static REQUIRED_COMPONENTS: std::sync::LazyLock<[ComponentDescriptor; 1usize]> =
319 std::sync::LazyLock::new(|| [Points3D::descriptor_positions()]);
320
321static RECOMMENDED_COMPONENTS: std::sync::LazyLock<[ComponentDescriptor; 2usize]> =
322 std::sync::LazyLock::new(|| [Points3D::descriptor_radii(), Points3D::descriptor_colors()]);
323
324static OPTIONAL_COMPONENTS: std::sync::LazyLock<[ComponentDescriptor; 4usize]> =
325 std::sync::LazyLock::new(|| {
326 [
327 Points3D::descriptor_labels(),
328 Points3D::descriptor_show_labels(),
329 Points3D::descriptor_class_ids(),
330 Points3D::descriptor_keypoint_ids(),
331 ]
332 });
333
334static ALL_COMPONENTS: std::sync::LazyLock<[ComponentDescriptor; 7usize]> =
335 std::sync::LazyLock::new(|| {
336 [
337 Points3D::descriptor_positions(),
338 Points3D::descriptor_radii(),
339 Points3D::descriptor_colors(),
340 Points3D::descriptor_labels(),
341 Points3D::descriptor_show_labels(),
342 Points3D::descriptor_class_ids(),
343 Points3D::descriptor_keypoint_ids(),
344 ]
345 });
346
347impl Points3D {
348 /// The total number of components in the archetype: 1 required, 2 recommended, 4 optional
349 pub const NUM_COMPONENTS: usize = 7usize;
350}
351
352impl ::re_types_core::Archetype for Points3D {
353 #[inline]
354 fn name() -> ::re_types_core::ArchetypeName {
355 "rerun.archetypes.Points3D".into()
356 }
357
358 #[inline]
359 fn display_name() -> &'static str {
360 "Points 3D"
361 }
362
363 #[inline]
364 fn required_components() -> ::std::borrow::Cow<'static, [ComponentDescriptor]> {
365 REQUIRED_COMPONENTS.as_slice().into()
366 }
367
368 #[inline]
369 fn recommended_components() -> ::std::borrow::Cow<'static, [ComponentDescriptor]> {
370 RECOMMENDED_COMPONENTS.as_slice().into()
371 }
372
373 #[inline]
374 fn optional_components() -> ::std::borrow::Cow<'static, [ComponentDescriptor]> {
375 OPTIONAL_COMPONENTS.as_slice().into()
376 }
377
378 #[inline]
379 fn all_components() -> ::std::borrow::Cow<'static, [ComponentDescriptor]> {
380 ALL_COMPONENTS.as_slice().into()
381 }
382
383 #[inline]
384 fn from_arrow_components(
385 arrow_data: impl IntoIterator<Item = (ComponentDescriptor, arrow::array::ArrayRef)>,
386 ) -> DeserializationResult<Self> {
387 re_tracing::profile_function!();
388 use ::re_types_core::{Loggable as _, ResultExt as _};
389 let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect();
390 let positions = arrays_by_descr
391 .get(&Self::descriptor_positions())
392 .map(|array| {
393 SerializedComponentBatch::new(array.clone(), Self::descriptor_positions())
394 });
395 let radii = arrays_by_descr
396 .get(&Self::descriptor_radii())
397 .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_radii()));
398 let colors = arrays_by_descr
399 .get(&Self::descriptor_colors())
400 .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_colors()));
401 let labels = arrays_by_descr
402 .get(&Self::descriptor_labels())
403 .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_labels()));
404 let show_labels = arrays_by_descr
405 .get(&Self::descriptor_show_labels())
406 .map(|array| {
407 SerializedComponentBatch::new(array.clone(), Self::descriptor_show_labels())
408 });
409 let class_ids = arrays_by_descr
410 .get(&Self::descriptor_class_ids())
411 .map(|array| {
412 SerializedComponentBatch::new(array.clone(), Self::descriptor_class_ids())
413 });
414 let keypoint_ids = arrays_by_descr
415 .get(&Self::descriptor_keypoint_ids())
416 .map(|array| {
417 SerializedComponentBatch::new(array.clone(), Self::descriptor_keypoint_ids())
418 });
419 Ok(Self {
420 positions,
421 radii,
422 colors,
423 labels,
424 show_labels,
425 class_ids,
426 keypoint_ids,
427 })
428 }
429}
430
431impl ::re_types_core::AsComponents for Points3D {
432 #[inline]
433 fn as_serialized_batches(&self) -> Vec<SerializedComponentBatch> {
434 use ::re_types_core::Archetype as _;
435 [
436 self.positions.clone(),
437 self.radii.clone(),
438 self.colors.clone(),
439 self.labels.clone(),
440 self.show_labels.clone(),
441 self.class_ids.clone(),
442 self.keypoint_ids.clone(),
443 ]
444 .into_iter()
445 .flatten()
446 .collect()
447 }
448}
449
450impl ::re_types_core::ArchetypeReflectionMarker for Points3D {}
451
452impl Points3D {
453 /// Create a new `Points3D`.
454 #[inline]
455 pub fn new(
456 positions: impl IntoIterator<Item = impl Into<crate::components::Position3D>>,
457 ) -> Self {
458 Self {
459 positions: try_serialize_field(Self::descriptor_positions(), positions),
460 radii: None,
461 colors: None,
462 labels: None,
463 show_labels: None,
464 class_ids: None,
465 keypoint_ids: None,
466 }
467 }
468
469 /// Update only some specific fields of a `Points3D`.
470 #[inline]
471 pub fn update_fields() -> Self {
472 Self::default()
473 }
474
475 /// Clear all the fields of a `Points3D`.
476 #[inline]
477 pub fn clear_fields() -> Self {
478 use ::re_types_core::Loggable as _;
479 Self {
480 positions: Some(SerializedComponentBatch::new(
481 crate::components::Position3D::arrow_empty(),
482 Self::descriptor_positions(),
483 )),
484 radii: Some(SerializedComponentBatch::new(
485 crate::components::Radius::arrow_empty(),
486 Self::descriptor_radii(),
487 )),
488 colors: Some(SerializedComponentBatch::new(
489 crate::components::Color::arrow_empty(),
490 Self::descriptor_colors(),
491 )),
492 labels: Some(SerializedComponentBatch::new(
493 crate::components::Text::arrow_empty(),
494 Self::descriptor_labels(),
495 )),
496 show_labels: Some(SerializedComponentBatch::new(
497 crate::components::ShowLabels::arrow_empty(),
498 Self::descriptor_show_labels(),
499 )),
500 class_ids: Some(SerializedComponentBatch::new(
501 crate::components::ClassId::arrow_empty(),
502 Self::descriptor_class_ids(),
503 )),
504 keypoint_ids: Some(SerializedComponentBatch::new(
505 crate::components::KeypointId::arrow_empty(),
506 Self::descriptor_keypoint_ids(),
507 )),
508 }
509 }
510
511 /// Partitions the component data into multiple sub-batches.
512 ///
513 /// Specifically, this transforms the existing [`SerializedComponentBatch`]es data into [`SerializedComponentColumn`]s
514 /// instead, via [`SerializedComponentBatch::partitioned`].
515 ///
516 /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun.
517 ///
518 /// The specified `lengths` must sum to the total length of the component batch.
519 ///
520 /// [`SerializedComponentColumn`]: [::re_types_core::SerializedComponentColumn]
521 #[inline]
522 pub fn columns<I>(
523 self,
524 _lengths: I,
525 ) -> SerializationResult<impl Iterator<Item = ::re_types_core::SerializedComponentColumn>>
526 where
527 I: IntoIterator<Item = usize> + Clone,
528 {
529 let columns = [
530 self.positions
531 .map(|positions| positions.partitioned(_lengths.clone()))
532 .transpose()?,
533 self.radii
534 .map(|radii| radii.partitioned(_lengths.clone()))
535 .transpose()?,
536 self.colors
537 .map(|colors| colors.partitioned(_lengths.clone()))
538 .transpose()?,
539 self.labels
540 .map(|labels| labels.partitioned(_lengths.clone()))
541 .transpose()?,
542 self.show_labels
543 .map(|show_labels| show_labels.partitioned(_lengths.clone()))
544 .transpose()?,
545 self.class_ids
546 .map(|class_ids| class_ids.partitioned(_lengths.clone()))
547 .transpose()?,
548 self.keypoint_ids
549 .map(|keypoint_ids| keypoint_ids.partitioned(_lengths.clone()))
550 .transpose()?,
551 ];
552 Ok(columns.into_iter().flatten())
553 }
554
555 /// Helper to partition the component data into unit-length sub-batches.
556 ///
557 /// This is semantically similar to calling [`Self::columns`] with `std::iter::take(1).repeat(n)`,
558 /// where `n` is automatically guessed.
559 #[inline]
560 pub fn columns_of_unit_batches(
561 self,
562 ) -> SerializationResult<impl Iterator<Item = ::re_types_core::SerializedComponentColumn>> {
563 let len_positions = self.positions.as_ref().map(|b| b.array.len());
564 let len_radii = self.radii.as_ref().map(|b| b.array.len());
565 let len_colors = self.colors.as_ref().map(|b| b.array.len());
566 let len_labels = self.labels.as_ref().map(|b| b.array.len());
567 let len_show_labels = self.show_labels.as_ref().map(|b| b.array.len());
568 let len_class_ids = self.class_ids.as_ref().map(|b| b.array.len());
569 let len_keypoint_ids = self.keypoint_ids.as_ref().map(|b| b.array.len());
570 let len = None
571 .or(len_positions)
572 .or(len_radii)
573 .or(len_colors)
574 .or(len_labels)
575 .or(len_show_labels)
576 .or(len_class_ids)
577 .or(len_keypoint_ids)
578 .unwrap_or(0);
579 self.columns(std::iter::repeat_n(1, len))
580 }
581
582 /// All the 3D positions at which the point cloud shows points.
583 #[inline]
584 pub fn with_positions(
585 mut self,
586 positions: impl IntoIterator<Item = impl Into<crate::components::Position3D>>,
587 ) -> Self {
588 self.positions = try_serialize_field(Self::descriptor_positions(), positions);
589 self
590 }
591
592 /// Optional radii for the points, effectively turning them into circles.
593 #[inline]
594 pub fn with_radii(
595 mut self,
596 radii: impl IntoIterator<Item = impl Into<crate::components::Radius>>,
597 ) -> Self {
598 self.radii = try_serialize_field(Self::descriptor_radii(), radii);
599 self
600 }
601
602 /// Optional colors for the points.
603 #[inline]
604 pub fn with_colors(
605 mut self,
606 colors: impl IntoIterator<Item = impl Into<crate::components::Color>>,
607 ) -> Self {
608 self.colors = try_serialize_field(Self::descriptor_colors(), colors);
609 self
610 }
611
612 /// Optional text labels for the points.
613 ///
614 /// If there's a single label present, it will be placed at the center of the entity.
615 /// Otherwise, each instance will have its own label.
616 #[inline]
617 pub fn with_labels(
618 mut self,
619 labels: impl IntoIterator<Item = impl Into<crate::components::Text>>,
620 ) -> Self {
621 self.labels = try_serialize_field(Self::descriptor_labels(), labels);
622 self
623 }
624
625 /// Whether the text labels should be shown.
626 ///
627 /// If not set, labels will automatically appear when there is exactly one label for this entity
628 /// or the number of instances on this entity is under a certain threshold.
629 #[inline]
630 pub fn with_show_labels(
631 mut self,
632 show_labels: impl Into<crate::components::ShowLabels>,
633 ) -> Self {
634 self.show_labels = try_serialize_field(Self::descriptor_show_labels(), [show_labels]);
635 self
636 }
637
638 /// This method makes it possible to pack multiple [`crate::components::ShowLabels`] in a single component batch.
639 ///
640 /// This only makes sense when used in conjunction with [`Self::columns`]. [`Self::with_show_labels`] should
641 /// be used when logging a single row's worth of data.
642 #[inline]
643 pub fn with_many_show_labels(
644 mut self,
645 show_labels: impl IntoIterator<Item = impl Into<crate::components::ShowLabels>>,
646 ) -> Self {
647 self.show_labels = try_serialize_field(Self::descriptor_show_labels(), show_labels);
648 self
649 }
650
651 /// Optional class Ids for the points.
652 ///
653 /// The [`components::ClassId`][crate::components::ClassId] provides colors and labels if not specified explicitly.
654 #[inline]
655 pub fn with_class_ids(
656 mut self,
657 class_ids: impl IntoIterator<Item = impl Into<crate::components::ClassId>>,
658 ) -> Self {
659 self.class_ids = try_serialize_field(Self::descriptor_class_ids(), class_ids);
660 self
661 }
662
663 /// Optional keypoint IDs for the points, identifying them within a class.
664 ///
665 /// If keypoint IDs are passed in but no [`components::ClassId`][crate::components::ClassId]s were specified, the [`components::ClassId`][crate::components::ClassId] will
666 /// default to 0.
667 /// This is useful to identify points within a single classification (which is identified
668 /// with `class_id`).
669 /// E.g. the classification might be 'Person' and the keypoints refer to joints on a
670 /// detected skeleton.
671 #[inline]
672 pub fn with_keypoint_ids(
673 mut self,
674 keypoint_ids: impl IntoIterator<Item = impl Into<crate::components::KeypointId>>,
675 ) -> Self {
676 self.keypoint_ids = try_serialize_field(Self::descriptor_keypoint_ids(), keypoint_ids);
677 self
678 }
679}
680
681impl ::re_byte_size::SizeBytes for Points3D {
682 #[inline]
683 fn heap_size_bytes(&self) -> u64 {
684 self.positions.heap_size_bytes()
685 + self.radii.heap_size_bytes()
686 + self.colors.heap_size_bytes()
687 + self.labels.heap_size_bytes()
688 + self.show_labels.heap_size_bytes()
689 + self.class_ids.heap_size_bytes()
690 + self.keypoint_ids.heap_size_bytes()
691 }
692}