pcd_rs/
metas.rs

1//! Types for PCD metadata.
2
3use std::{iter::FromIterator, ops::Index};
4
5/// The struct keep meta data of PCD file.
6#[derive(Debug, Clone, PartialEq)]
7pub struct PcdMeta {
8    pub version: String,
9    pub width: u64,
10    pub height: u64,
11    pub viewpoint: ViewPoint,
12    pub num_points: u64,
13    pub data: DataKind,
14    pub field_defs: Schema,
15}
16
17/// Represents VIEWPOINT field in meta data.
18#[derive(Debug, Clone, PartialEq)]
19pub struct ViewPoint {
20    pub tx: f64,
21    pub ty: f64,
22    pub tz: f64,
23    pub qw: f64,
24    pub qx: f64,
25    pub qy: f64,
26    pub qz: f64,
27}
28
29impl Default for ViewPoint {
30    fn default() -> Self {
31        ViewPoint {
32            tx: 0.0,
33            ty: 0.0,
34            tz: 0.0,
35            qw: 1.0,
36            qx: 0.0,
37            qy: 0.0,
38            qz: 0.0,
39        }
40    }
41}
42
43/// The enum indicates whether the point cloud data is encoded in Ascii or binary.
44#[derive(Debug, Clone, Copy, PartialEq, Eq)]
45pub enum DataKind {
46    Ascii,
47    Binary,
48}
49
50/// The enum specifies one of signed, unsigned integers, and floating point number type to the field.
51#[derive(Debug, Clone, Copy, PartialEq, Eq)]
52pub enum TypeKind {
53    I,
54    U,
55    F,
56}
57
58/// The enum specifies the exact type for each PCD field.
59#[derive(Debug, Clone, Copy, PartialEq, Eq)]
60pub enum ValueKind {
61    U8,
62    U16,
63    U32,
64    I8,
65    I16,
66    I32,
67    F32,
68    F64,
69}
70
71/// Define the properties of a PCD field.
72#[derive(Debug, Clone, PartialEq, Eq)]
73pub struct FieldDef {
74    pub name: String,
75    pub kind: ValueKind,
76    pub count: u64,
77}
78
79/// Define the schema of PCD format.
80#[derive(Debug, Clone, PartialEq, Eq)]
81pub struct Schema {
82    pub fields: Vec<FieldDef>,
83}
84
85impl Schema {
86    pub fn is_empty(&self) -> bool {
87        self.fields.is_empty()
88    }
89
90    pub fn len(&self) -> usize {
91        self.fields.len()
92    }
93
94    pub fn iter(&self) -> std::slice::Iter<'_, FieldDef> {
95        self.into_iter()
96    }
97}
98
99impl Index<usize> for Schema {
100    type Output = FieldDef;
101
102    fn index(&self, index: usize) -> &Self::Output {
103        self.fields.index(index)
104    }
105}
106
107impl IntoIterator for Schema {
108    type Item = FieldDef;
109    type IntoIter = std::vec::IntoIter<FieldDef>;
110
111    fn into_iter(self) -> Self::IntoIter {
112        self.fields.into_iter()
113    }
114}
115
116impl<'a> IntoIterator for &'a Schema {
117    type Item = &'a FieldDef;
118    type IntoIter = std::slice::Iter<'a, FieldDef>;
119
120    fn into_iter(self) -> Self::IntoIter {
121        self.fields.iter()
122    }
123}
124
125impl FromIterator<(String, ValueKind, u64)> for Schema {
126    fn from_iter<T: IntoIterator<Item = (String, ValueKind, u64)>>(iter: T) -> Self {
127        let fields = iter
128            .into_iter()
129            .map(|(name, kind, count)| FieldDef { name, kind, count })
130            .collect();
131        Self { fields }
132    }
133}
134
135impl<'a> FromIterator<(&'a str, ValueKind, u64)> for Schema {
136    fn from_iter<T: IntoIterator<Item = (&'a str, ValueKind, u64)>>(iter: T) -> Self {
137        iter.into_iter()
138            .map(|(name, kind, count)| (name.to_string(), kind, count))
139            .collect()
140    }
141}
142
143impl FromIterator<FieldDef> for Schema {
144    fn from_iter<T: IntoIterator<Item = FieldDef>>(iter: T) -> Self {
145        Self {
146            fields: iter.into_iter().collect(),
147        }
148    }
149}
150
151impl<'a> FromIterator<&'a FieldDef> for Schema {
152    fn from_iter<T: IntoIterator<Item = &'a FieldDef>>(iter: T) -> Self {
153        Self {
154            fields: iter.into_iter().map(|field| field.to_owned()).collect(),
155        }
156    }
157}