re_types/archetypes/
cylinders3d.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/cylinders3d.fbs".
3
4#![allow(unused_braces)]
5#![allow(unused_imports)]
6#![allow(unused_parens)]
7#![allow(clippy::clone_on_copy)]
8#![allow(clippy::cloned_instead_of_copied)]
9#![allow(clippy::map_flatten)]
10#![allow(clippy::needless_question_mark)]
11#![allow(clippy::new_without_default)]
12#![allow(clippy::redundant_closure)]
13#![allow(clippy::too_many_arguments)]
14#![allow(clippy::too_many_lines)]
15
16use ::re_types_core::try_serialize_field;
17use ::re_types_core::SerializationResult;
18use ::re_types_core::{ComponentBatch as _, SerializedComponentBatch};
19use ::re_types_core::{ComponentDescriptor, ComponentType};
20use ::re_types_core::{DeserializationError, DeserializationResult};
21
22/// **Archetype**: 3D cylinders with flat caps.
23///
24/// This archetype is for cylinder primitives defined by their axial length and radius.
25/// For points whose radii are for visualization purposes, use [`archetypes::Points3D`][crate::archetypes::Points3D] instead.
26///
27/// Orienting and placing cylinders forms a separate transform that is applied prior to [`archetypes::InstancePoses3D`][crate::archetypes::InstancePoses3D] and [`archetypes::Transform3D`][crate::archetypes::Transform3D].
28///
29/// ## Example
30///
31/// ### Batch of cylinders
32/// ```ignore
33/// use rerun::external::glam::vec3;
34///
35/// fn main() -> Result<(), Box<dyn std::error::Error>> {
36///     let rec = rerun::RecordingStreamBuilder::new("rerun_example_cylinders3d_batch").spawn()?;
37///
38///     rec.log(
39///         "cylinders",
40///         &rerun::Cylinders3D::from_lengths_and_radii(
41///             [0.0, 2.0, 4.0, 6.0, 8.0],
42///             [1.0, 0.5, 0.5, 0.5, 1.0],
43///         )
44///         .with_colors([
45///             rerun::Color::from_rgb(255, 0, 0),
46///             rerun::Color::from_rgb(188, 188, 0),
47///             rerun::Color::from_rgb(0, 255, 0),
48///             rerun::Color::from_rgb(0, 188, 188),
49///             rerun::Color::from_rgb(0, 0, 255),
50///         ])
51///         .with_centers([
52///             vec3(0., 0., 0.),
53///             vec3(2., 0., 0.),
54///             vec3(4., 0., 0.),
55///             vec3(6., 0., 0.),
56///             vec3(8., 0., 0.),
57///         ])
58///         .with_rotation_axis_angles((0..5).map(|i| {
59///             rerun::RotationAxisAngle::new(
60///                 [1.0, 0.0, 0.0],
61///                 rerun::Angle::from_degrees(i as f32 * -22.5),
62///             )
63///         })),
64///     )?;
65///
66///     Ok(())
67/// }
68/// ```
69/// <center>
70/// <picture>
71///   <source media="(max-width: 480px)" srcset="https://static.rerun.io/cylinders3d_batch/ef642dede2bef23704eaff0f22aa48284d482b23/480w.png">
72///   <source media="(max-width: 768px)" srcset="https://static.rerun.io/cylinders3d_batch/ef642dede2bef23704eaff0f22aa48284d482b23/768w.png">
73///   <source media="(max-width: 1024px)" srcset="https://static.rerun.io/cylinders3d_batch/ef642dede2bef23704eaff0f22aa48284d482b23/1024w.png">
74///   <source media="(max-width: 1200px)" srcset="https://static.rerun.io/cylinders3d_batch/ef642dede2bef23704eaff0f22aa48284d482b23/1200w.png">
75///   <img src="https://static.rerun.io/cylinders3d_batch/ef642dede2bef23704eaff0f22aa48284d482b23/full.png" width="640">
76/// </picture>
77/// </center>
78#[derive(Clone, Debug, PartialEq, Default)]
79pub struct Cylinders3D {
80    /// The total axial length of the cylinder, measured as the straight-line distance between the centers of its two endcaps.
81    pub lengths: Option<SerializedComponentBatch>,
82
83    /// Radii of the cylinders.
84    pub radii: Option<SerializedComponentBatch>,
85
86    /// Optional centers of the cylinders.
87    ///
88    /// If not specified, each cylinder will be centered at (0, 0, 0).
89    pub centers: Option<SerializedComponentBatch>,
90
91    /// Rotations via axis + angle.
92    ///
93    /// If no rotation is specified, the cylinders align with the +Z axis of the local coordinate system.
94    pub rotation_axis_angles: Option<SerializedComponentBatch>,
95
96    /// Rotations via quaternion.
97    ///
98    /// If no rotation is specified, the cylinders align with the +Z axis of the local coordinate system.
99    pub quaternions: Option<SerializedComponentBatch>,
100
101    /// Optional colors for the cylinders.
102    pub colors: Option<SerializedComponentBatch>,
103
104    /// Optional radii for the lines used when the cylinder is rendered as a wireframe.
105    pub line_radii: Option<SerializedComponentBatch>,
106
107    /// Optionally choose whether the cylinders are drawn with lines or solid.
108    pub fill_mode: Option<SerializedComponentBatch>,
109
110    /// Optional text labels for the cylinders, which will be located at their centers.
111    pub labels: Option<SerializedComponentBatch>,
112
113    /// Whether the text labels should be shown.
114    ///
115    /// If not set, labels will automatically appear when there is exactly one label for this entity
116    /// or the number of instances on this entity is under a certain threshold.
117    pub show_labels: Option<SerializedComponentBatch>,
118
119    /// Optional class ID for the ellipsoids.
120    ///
121    /// The class ID provides colors and labels if not specified explicitly.
122    pub class_ids: Option<SerializedComponentBatch>,
123}
124
125impl Cylinders3D {
126    /// Returns the [`ComponentDescriptor`] for [`Self::lengths`].
127    ///
128    /// The corresponding component is [`crate::components::Length`].
129    #[inline]
130    pub fn descriptor_lengths() -> ComponentDescriptor {
131        ComponentDescriptor {
132            archetype: Some("rerun.archetypes.Cylinders3D".into()),
133            component: "Cylinders3D:lengths".into(),
134            component_type: Some("rerun.components.Length".into()),
135        }
136    }
137
138    /// Returns the [`ComponentDescriptor`] for [`Self::radii`].
139    ///
140    /// The corresponding component is [`crate::components::Radius`].
141    #[inline]
142    pub fn descriptor_radii() -> ComponentDescriptor {
143        ComponentDescriptor {
144            archetype: Some("rerun.archetypes.Cylinders3D".into()),
145            component: "Cylinders3D:radii".into(),
146            component_type: Some("rerun.components.Radius".into()),
147        }
148    }
149
150    /// Returns the [`ComponentDescriptor`] for [`Self::centers`].
151    ///
152    /// The corresponding component is [`crate::components::PoseTranslation3D`].
153    #[inline]
154    pub fn descriptor_centers() -> ComponentDescriptor {
155        ComponentDescriptor {
156            archetype: Some("rerun.archetypes.Cylinders3D".into()),
157            component: "Cylinders3D:centers".into(),
158            component_type: Some("rerun.components.PoseTranslation3D".into()),
159        }
160    }
161
162    /// Returns the [`ComponentDescriptor`] for [`Self::rotation_axis_angles`].
163    ///
164    /// The corresponding component is [`crate::components::PoseRotationAxisAngle`].
165    #[inline]
166    pub fn descriptor_rotation_axis_angles() -> ComponentDescriptor {
167        ComponentDescriptor {
168            archetype: Some("rerun.archetypes.Cylinders3D".into()),
169            component: "Cylinders3D:rotation_axis_angles".into(),
170            component_type: Some("rerun.components.PoseRotationAxisAngle".into()),
171        }
172    }
173
174    /// Returns the [`ComponentDescriptor`] for [`Self::quaternions`].
175    ///
176    /// The corresponding component is [`crate::components::PoseRotationQuat`].
177    #[inline]
178    pub fn descriptor_quaternions() -> ComponentDescriptor {
179        ComponentDescriptor {
180            archetype: Some("rerun.archetypes.Cylinders3D".into()),
181            component: "Cylinders3D:quaternions".into(),
182            component_type: Some("rerun.components.PoseRotationQuat".into()),
183        }
184    }
185
186    /// Returns the [`ComponentDescriptor`] for [`Self::colors`].
187    ///
188    /// The corresponding component is [`crate::components::Color`].
189    #[inline]
190    pub fn descriptor_colors() -> ComponentDescriptor {
191        ComponentDescriptor {
192            archetype: Some("rerun.archetypes.Cylinders3D".into()),
193            component: "Cylinders3D:colors".into(),
194            component_type: Some("rerun.components.Color".into()),
195        }
196    }
197
198    /// Returns the [`ComponentDescriptor`] for [`Self::line_radii`].
199    ///
200    /// The corresponding component is [`crate::components::Radius`].
201    #[inline]
202    pub fn descriptor_line_radii() -> ComponentDescriptor {
203        ComponentDescriptor {
204            archetype: Some("rerun.archetypes.Cylinders3D".into()),
205            component: "Cylinders3D:line_radii".into(),
206            component_type: Some("rerun.components.Radius".into()),
207        }
208    }
209
210    /// Returns the [`ComponentDescriptor`] for [`Self::fill_mode`].
211    ///
212    /// The corresponding component is [`crate::components::FillMode`].
213    #[inline]
214    pub fn descriptor_fill_mode() -> ComponentDescriptor {
215        ComponentDescriptor {
216            archetype: Some("rerun.archetypes.Cylinders3D".into()),
217            component: "Cylinders3D:fill_mode".into(),
218            component_type: Some("rerun.components.FillMode".into()),
219        }
220    }
221
222    /// Returns the [`ComponentDescriptor`] for [`Self::labels`].
223    ///
224    /// The corresponding component is [`crate::components::Text`].
225    #[inline]
226    pub fn descriptor_labels() -> ComponentDescriptor {
227        ComponentDescriptor {
228            archetype: Some("rerun.archetypes.Cylinders3D".into()),
229            component: "Cylinders3D:labels".into(),
230            component_type: Some("rerun.components.Text".into()),
231        }
232    }
233
234    /// Returns the [`ComponentDescriptor`] for [`Self::show_labels`].
235    ///
236    /// The corresponding component is [`crate::components::ShowLabels`].
237    #[inline]
238    pub fn descriptor_show_labels() -> ComponentDescriptor {
239        ComponentDescriptor {
240            archetype: Some("rerun.archetypes.Cylinders3D".into()),
241            component: "Cylinders3D:show_labels".into(),
242            component_type: Some("rerun.components.ShowLabels".into()),
243        }
244    }
245
246    /// Returns the [`ComponentDescriptor`] for [`Self::class_ids`].
247    ///
248    /// The corresponding component is [`crate::components::ClassId`].
249    #[inline]
250    pub fn descriptor_class_ids() -> ComponentDescriptor {
251        ComponentDescriptor {
252            archetype: Some("rerun.archetypes.Cylinders3D".into()),
253            component: "Cylinders3D:class_ids".into(),
254            component_type: Some("rerun.components.ClassId".into()),
255        }
256    }
257}
258
259static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 2usize]> =
260    once_cell::sync::Lazy::new(|| {
261        [
262            Cylinders3D::descriptor_lengths(),
263            Cylinders3D::descriptor_radii(),
264        ]
265    });
266
267static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 2usize]> =
268    once_cell::sync::Lazy::new(|| {
269        [
270            Cylinders3D::descriptor_centers(),
271            Cylinders3D::descriptor_colors(),
272        ]
273    });
274
275static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 7usize]> =
276    once_cell::sync::Lazy::new(|| {
277        [
278            Cylinders3D::descriptor_rotation_axis_angles(),
279            Cylinders3D::descriptor_quaternions(),
280            Cylinders3D::descriptor_line_radii(),
281            Cylinders3D::descriptor_fill_mode(),
282            Cylinders3D::descriptor_labels(),
283            Cylinders3D::descriptor_show_labels(),
284            Cylinders3D::descriptor_class_ids(),
285        ]
286    });
287
288static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 11usize]> =
289    once_cell::sync::Lazy::new(|| {
290        [
291            Cylinders3D::descriptor_lengths(),
292            Cylinders3D::descriptor_radii(),
293            Cylinders3D::descriptor_centers(),
294            Cylinders3D::descriptor_colors(),
295            Cylinders3D::descriptor_rotation_axis_angles(),
296            Cylinders3D::descriptor_quaternions(),
297            Cylinders3D::descriptor_line_radii(),
298            Cylinders3D::descriptor_fill_mode(),
299            Cylinders3D::descriptor_labels(),
300            Cylinders3D::descriptor_show_labels(),
301            Cylinders3D::descriptor_class_ids(),
302        ]
303    });
304
305impl Cylinders3D {
306    /// The total number of components in the archetype: 2 required, 2 recommended, 7 optional
307    pub const NUM_COMPONENTS: usize = 11usize;
308}
309
310impl ::re_types_core::Archetype for Cylinders3D {
311    #[inline]
312    fn name() -> ::re_types_core::ArchetypeName {
313        "rerun.archetypes.Cylinders3D".into()
314    }
315
316    #[inline]
317    fn display_name() -> &'static str {
318        "Cylinders 3D"
319    }
320
321    #[inline]
322    fn required_components() -> ::std::borrow::Cow<'static, [ComponentDescriptor]> {
323        REQUIRED_COMPONENTS.as_slice().into()
324    }
325
326    #[inline]
327    fn recommended_components() -> ::std::borrow::Cow<'static, [ComponentDescriptor]> {
328        RECOMMENDED_COMPONENTS.as_slice().into()
329    }
330
331    #[inline]
332    fn optional_components() -> ::std::borrow::Cow<'static, [ComponentDescriptor]> {
333        OPTIONAL_COMPONENTS.as_slice().into()
334    }
335
336    #[inline]
337    fn all_components() -> ::std::borrow::Cow<'static, [ComponentDescriptor]> {
338        ALL_COMPONENTS.as_slice().into()
339    }
340
341    #[inline]
342    fn from_arrow_components(
343        arrow_data: impl IntoIterator<Item = (ComponentDescriptor, arrow::array::ArrayRef)>,
344    ) -> DeserializationResult<Self> {
345        re_tracing::profile_function!();
346        use ::re_types_core::{Loggable as _, ResultExt as _};
347        let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect();
348        let lengths = arrays_by_descr
349            .get(&Self::descriptor_lengths())
350            .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_lengths()));
351        let radii = arrays_by_descr
352            .get(&Self::descriptor_radii())
353            .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_radii()));
354        let centers = arrays_by_descr
355            .get(&Self::descriptor_centers())
356            .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_centers()));
357        let rotation_axis_angles = arrays_by_descr
358            .get(&Self::descriptor_rotation_axis_angles())
359            .map(|array| {
360                SerializedComponentBatch::new(
361                    array.clone(),
362                    Self::descriptor_rotation_axis_angles(),
363                )
364            });
365        let quaternions = arrays_by_descr
366            .get(&Self::descriptor_quaternions())
367            .map(|array| {
368                SerializedComponentBatch::new(array.clone(), Self::descriptor_quaternions())
369            });
370        let colors = arrays_by_descr
371            .get(&Self::descriptor_colors())
372            .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_colors()));
373        let line_radii = arrays_by_descr
374            .get(&Self::descriptor_line_radii())
375            .map(|array| {
376                SerializedComponentBatch::new(array.clone(), Self::descriptor_line_radii())
377            });
378        let fill_mode = arrays_by_descr
379            .get(&Self::descriptor_fill_mode())
380            .map(|array| {
381                SerializedComponentBatch::new(array.clone(), Self::descriptor_fill_mode())
382            });
383        let labels = arrays_by_descr
384            .get(&Self::descriptor_labels())
385            .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_labels()));
386        let show_labels = arrays_by_descr
387            .get(&Self::descriptor_show_labels())
388            .map(|array| {
389                SerializedComponentBatch::new(array.clone(), Self::descriptor_show_labels())
390            });
391        let class_ids = arrays_by_descr
392            .get(&Self::descriptor_class_ids())
393            .map(|array| {
394                SerializedComponentBatch::new(array.clone(), Self::descriptor_class_ids())
395            });
396        Ok(Self {
397            lengths,
398            radii,
399            centers,
400            rotation_axis_angles,
401            quaternions,
402            colors,
403            line_radii,
404            fill_mode,
405            labels,
406            show_labels,
407            class_ids,
408        })
409    }
410}
411
412impl ::re_types_core::AsComponents for Cylinders3D {
413    #[inline]
414    fn as_serialized_batches(&self) -> Vec<SerializedComponentBatch> {
415        use ::re_types_core::Archetype as _;
416        [
417            self.lengths.clone(),
418            self.radii.clone(),
419            self.centers.clone(),
420            self.rotation_axis_angles.clone(),
421            self.quaternions.clone(),
422            self.colors.clone(),
423            self.line_radii.clone(),
424            self.fill_mode.clone(),
425            self.labels.clone(),
426            self.show_labels.clone(),
427            self.class_ids.clone(),
428        ]
429        .into_iter()
430        .flatten()
431        .collect()
432    }
433}
434
435impl ::re_types_core::ArchetypeReflectionMarker for Cylinders3D {}
436
437impl Cylinders3D {
438    /// Create a new `Cylinders3D`.
439    #[inline]
440    pub(crate) fn new(
441        lengths: impl IntoIterator<Item = impl Into<crate::components::Length>>,
442        radii: impl IntoIterator<Item = impl Into<crate::components::Radius>>,
443    ) -> Self {
444        Self {
445            lengths: try_serialize_field(Self::descriptor_lengths(), lengths),
446            radii: try_serialize_field(Self::descriptor_radii(), radii),
447            centers: None,
448            rotation_axis_angles: None,
449            quaternions: None,
450            colors: None,
451            line_radii: None,
452            fill_mode: None,
453            labels: None,
454            show_labels: None,
455            class_ids: None,
456        }
457    }
458
459    /// Update only some specific fields of a `Cylinders3D`.
460    #[inline]
461    pub fn update_fields() -> Self {
462        Self::default()
463    }
464
465    /// Clear all the fields of a `Cylinders3D`.
466    #[inline]
467    pub fn clear_fields() -> Self {
468        use ::re_types_core::Loggable as _;
469        Self {
470            lengths: Some(SerializedComponentBatch::new(
471                crate::components::Length::arrow_empty(),
472                Self::descriptor_lengths(),
473            )),
474            radii: Some(SerializedComponentBatch::new(
475                crate::components::Radius::arrow_empty(),
476                Self::descriptor_radii(),
477            )),
478            centers: Some(SerializedComponentBatch::new(
479                crate::components::PoseTranslation3D::arrow_empty(),
480                Self::descriptor_centers(),
481            )),
482            rotation_axis_angles: Some(SerializedComponentBatch::new(
483                crate::components::PoseRotationAxisAngle::arrow_empty(),
484                Self::descriptor_rotation_axis_angles(),
485            )),
486            quaternions: Some(SerializedComponentBatch::new(
487                crate::components::PoseRotationQuat::arrow_empty(),
488                Self::descriptor_quaternions(),
489            )),
490            colors: Some(SerializedComponentBatch::new(
491                crate::components::Color::arrow_empty(),
492                Self::descriptor_colors(),
493            )),
494            line_radii: Some(SerializedComponentBatch::new(
495                crate::components::Radius::arrow_empty(),
496                Self::descriptor_line_radii(),
497            )),
498            fill_mode: Some(SerializedComponentBatch::new(
499                crate::components::FillMode::arrow_empty(),
500                Self::descriptor_fill_mode(),
501            )),
502            labels: Some(SerializedComponentBatch::new(
503                crate::components::Text::arrow_empty(),
504                Self::descriptor_labels(),
505            )),
506            show_labels: Some(SerializedComponentBatch::new(
507                crate::components::ShowLabels::arrow_empty(),
508                Self::descriptor_show_labels(),
509            )),
510            class_ids: Some(SerializedComponentBatch::new(
511                crate::components::ClassId::arrow_empty(),
512                Self::descriptor_class_ids(),
513            )),
514        }
515    }
516
517    /// Partitions the component data into multiple sub-batches.
518    ///
519    /// Specifically, this transforms the existing [`SerializedComponentBatch`]es data into [`SerializedComponentColumn`]s
520    /// instead, via [`SerializedComponentBatch::partitioned`].
521    ///
522    /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun.
523    ///
524    /// The specified `lengths` must sum to the total length of the component batch.
525    ///
526    /// [`SerializedComponentColumn`]: [::re_types_core::SerializedComponentColumn]
527    #[inline]
528    pub fn columns<I>(
529        self,
530        _lengths: I,
531    ) -> SerializationResult<impl Iterator<Item = ::re_types_core::SerializedComponentColumn>>
532    where
533        I: IntoIterator<Item = usize> + Clone,
534    {
535        let columns = [
536            self.lengths
537                .map(|lengths| lengths.partitioned(_lengths.clone()))
538                .transpose()?,
539            self.radii
540                .map(|radii| radii.partitioned(_lengths.clone()))
541                .transpose()?,
542            self.centers
543                .map(|centers| centers.partitioned(_lengths.clone()))
544                .transpose()?,
545            self.rotation_axis_angles
546                .map(|rotation_axis_angles| rotation_axis_angles.partitioned(_lengths.clone()))
547                .transpose()?,
548            self.quaternions
549                .map(|quaternions| quaternions.partitioned(_lengths.clone()))
550                .transpose()?,
551            self.colors
552                .map(|colors| colors.partitioned(_lengths.clone()))
553                .transpose()?,
554            self.line_radii
555                .map(|line_radii| line_radii.partitioned(_lengths.clone()))
556                .transpose()?,
557            self.fill_mode
558                .map(|fill_mode| fill_mode.partitioned(_lengths.clone()))
559                .transpose()?,
560            self.labels
561                .map(|labels| labels.partitioned(_lengths.clone()))
562                .transpose()?,
563            self.show_labels
564                .map(|show_labels| show_labels.partitioned(_lengths.clone()))
565                .transpose()?,
566            self.class_ids
567                .map(|class_ids| class_ids.partitioned(_lengths.clone()))
568                .transpose()?,
569        ];
570        Ok(columns.into_iter().flatten())
571    }
572
573    /// Helper to partition the component data into unit-length sub-batches.
574    ///
575    /// This is semantically similar to calling [`Self::columns`] with `std::iter::take(1).repeat(n)`,
576    /// where `n` is automatically guessed.
577    #[inline]
578    pub fn columns_of_unit_batches(
579        self,
580    ) -> SerializationResult<impl Iterator<Item = ::re_types_core::SerializedComponentColumn>> {
581        let len_lengths = self.lengths.as_ref().map(|b| b.array.len());
582        let len_radii = self.radii.as_ref().map(|b| b.array.len());
583        let len_centers = self.centers.as_ref().map(|b| b.array.len());
584        let len_rotation_axis_angles = self.rotation_axis_angles.as_ref().map(|b| b.array.len());
585        let len_quaternions = self.quaternions.as_ref().map(|b| b.array.len());
586        let len_colors = self.colors.as_ref().map(|b| b.array.len());
587        let len_line_radii = self.line_radii.as_ref().map(|b| b.array.len());
588        let len_fill_mode = self.fill_mode.as_ref().map(|b| b.array.len());
589        let len_labels = self.labels.as_ref().map(|b| b.array.len());
590        let len_show_labels = self.show_labels.as_ref().map(|b| b.array.len());
591        let len_class_ids = self.class_ids.as_ref().map(|b| b.array.len());
592        let len = None
593            .or(len_lengths)
594            .or(len_radii)
595            .or(len_centers)
596            .or(len_rotation_axis_angles)
597            .or(len_quaternions)
598            .or(len_colors)
599            .or(len_line_radii)
600            .or(len_fill_mode)
601            .or(len_labels)
602            .or(len_show_labels)
603            .or(len_class_ids)
604            .unwrap_or(0);
605        self.columns(std::iter::repeat(1).take(len))
606    }
607
608    /// The total axial length of the cylinder, measured as the straight-line distance between the centers of its two endcaps.
609    #[inline]
610    pub fn with_lengths(
611        mut self,
612        lengths: impl IntoIterator<Item = impl Into<crate::components::Length>>,
613    ) -> Self {
614        self.lengths = try_serialize_field(Self::descriptor_lengths(), lengths);
615        self
616    }
617
618    /// Radii of the cylinders.
619    #[inline]
620    pub fn with_radii(
621        mut self,
622        radii: impl IntoIterator<Item = impl Into<crate::components::Radius>>,
623    ) -> Self {
624        self.radii = try_serialize_field(Self::descriptor_radii(), radii);
625        self
626    }
627
628    /// Optional centers of the cylinders.
629    ///
630    /// If not specified, each cylinder will be centered at (0, 0, 0).
631    #[inline]
632    pub fn with_centers(
633        mut self,
634        centers: impl IntoIterator<Item = impl Into<crate::components::PoseTranslation3D>>,
635    ) -> Self {
636        self.centers = try_serialize_field(Self::descriptor_centers(), centers);
637        self
638    }
639
640    /// Rotations via axis + angle.
641    ///
642    /// If no rotation is specified, the cylinders align with the +Z axis of the local coordinate system.
643    #[inline]
644    pub fn with_rotation_axis_angles(
645        mut self,
646        rotation_axis_angles: impl IntoIterator<
647            Item = impl Into<crate::components::PoseRotationAxisAngle>,
648        >,
649    ) -> Self {
650        self.rotation_axis_angles = try_serialize_field(
651            Self::descriptor_rotation_axis_angles(),
652            rotation_axis_angles,
653        );
654        self
655    }
656
657    /// Rotations via quaternion.
658    ///
659    /// If no rotation is specified, the cylinders align with the +Z axis of the local coordinate system.
660    #[inline]
661    pub fn with_quaternions(
662        mut self,
663        quaternions: impl IntoIterator<Item = impl Into<crate::components::PoseRotationQuat>>,
664    ) -> Self {
665        self.quaternions = try_serialize_field(Self::descriptor_quaternions(), quaternions);
666        self
667    }
668
669    /// Optional colors for the cylinders.
670    #[inline]
671    pub fn with_colors(
672        mut self,
673        colors: impl IntoIterator<Item = impl Into<crate::components::Color>>,
674    ) -> Self {
675        self.colors = try_serialize_field(Self::descriptor_colors(), colors);
676        self
677    }
678
679    /// Optional radii for the lines used when the cylinder is rendered as a wireframe.
680    #[inline]
681    pub fn with_line_radii(
682        mut self,
683        line_radii: impl IntoIterator<Item = impl Into<crate::components::Radius>>,
684    ) -> Self {
685        self.line_radii = try_serialize_field(Self::descriptor_line_radii(), line_radii);
686        self
687    }
688
689    /// Optionally choose whether the cylinders are drawn with lines or solid.
690    #[inline]
691    pub fn with_fill_mode(mut self, fill_mode: impl Into<crate::components::FillMode>) -> Self {
692        self.fill_mode = try_serialize_field(Self::descriptor_fill_mode(), [fill_mode]);
693        self
694    }
695
696    /// This method makes it possible to pack multiple [`crate::components::FillMode`] in a single component batch.
697    ///
698    /// This only makes sense when used in conjunction with [`Self::columns`]. [`Self::with_fill_mode`] should
699    /// be used when logging a single row's worth of data.
700    #[inline]
701    pub fn with_many_fill_mode(
702        mut self,
703        fill_mode: impl IntoIterator<Item = impl Into<crate::components::FillMode>>,
704    ) -> Self {
705        self.fill_mode = try_serialize_field(Self::descriptor_fill_mode(), fill_mode);
706        self
707    }
708
709    /// Optional text labels for the cylinders, which will be located at their centers.
710    #[inline]
711    pub fn with_labels(
712        mut self,
713        labels: impl IntoIterator<Item = impl Into<crate::components::Text>>,
714    ) -> Self {
715        self.labels = try_serialize_field(Self::descriptor_labels(), labels);
716        self
717    }
718
719    /// Whether the text labels should be shown.
720    ///
721    /// If not set, labels will automatically appear when there is exactly one label for this entity
722    /// or the number of instances on this entity is under a certain threshold.
723    #[inline]
724    pub fn with_show_labels(
725        mut self,
726        show_labels: impl Into<crate::components::ShowLabels>,
727    ) -> Self {
728        self.show_labels = try_serialize_field(Self::descriptor_show_labels(), [show_labels]);
729        self
730    }
731
732    /// This method makes it possible to pack multiple [`crate::components::ShowLabels`] in a single component batch.
733    ///
734    /// This only makes sense when used in conjunction with [`Self::columns`]. [`Self::with_show_labels`] should
735    /// be used when logging a single row's worth of data.
736    #[inline]
737    pub fn with_many_show_labels(
738        mut self,
739        show_labels: impl IntoIterator<Item = impl Into<crate::components::ShowLabels>>,
740    ) -> Self {
741        self.show_labels = try_serialize_field(Self::descriptor_show_labels(), show_labels);
742        self
743    }
744
745    /// Optional class ID for the ellipsoids.
746    ///
747    /// The class ID provides colors and labels if not specified explicitly.
748    #[inline]
749    pub fn with_class_ids(
750        mut self,
751        class_ids: impl IntoIterator<Item = impl Into<crate::components::ClassId>>,
752    ) -> Self {
753        self.class_ids = try_serialize_field(Self::descriptor_class_ids(), class_ids);
754        self
755    }
756}
757
758impl ::re_byte_size::SizeBytes for Cylinders3D {
759    #[inline]
760    fn heap_size_bytes(&self) -> u64 {
761        self.lengths.heap_size_bytes()
762            + self.radii.heap_size_bytes()
763            + self.centers.heap_size_bytes()
764            + self.rotation_axis_angles.heap_size_bytes()
765            + self.quaternions.heap_size_bytes()
766            + self.colors.heap_size_bytes()
767            + self.line_radii.heap_size_bytes()
768            + self.fill_mode.heap_size_bytes()
769            + self.labels.heap_size_bytes()
770            + self.show_labels.heap_size_bytes()
771            + self.class_ids.heap_size_bytes()
772    }
773}