1#![allow(non_snake_case)]
20
21use serde::{Deserialize, Deserializer, Serialize, Serializer};
22
23use nalgebra::allocator::Allocator;
24use nalgebra::core::dimension::{U3, U4};
25use nalgebra::core::{Matrix3, OMatrix, Vector5};
26use nalgebra::dimension::DimName;
27use nalgebra::geometry::Point3;
28use nalgebra::DefaultAllocator;
29use nalgebra::RealField;
30
31#[derive(Debug, Serialize, Deserialize)]
36#[serde(deny_unknown_fields)]
37pub struct PymvgMultiCameraSystemV1<R: RealField> {
38 pub(crate) __pymvg_file_version__: String,
39 pub(crate) camera_system: Vec<PymvgCamera<R>>,
40}
41
42#[derive(Debug, Serialize, Deserialize)]
48#[serde(deny_unknown_fields)]
49pub struct PymvgCamera<R: RealField> {
50 pub(crate) name: String,
51 pub(crate) width: usize,
52 pub(crate) height: usize,
53 #[serde(with = "array_of_arrays")]
54 pub(crate) P: OMatrix<R, U3, U4>,
55 #[serde(with = "array_of_arrays")]
56 pub(crate) K: Matrix3<R>,
57 pub(crate) D: Vector5<R>,
58 #[serde(with = "array_of_arrays")]
59 pub(crate) R: Matrix3<R>,
60 #[serde(with = "array_of_arrays")]
61 pub(crate) Q: Matrix3<R>,
62 pub(crate) translation: Point3<R>,
63}
64
65mod array_of_arrays {
66 use super::*;
67
68 pub fn serialize<S, R, ROWS, COLS>(
73 arr: &OMatrix<R, ROWS, COLS>,
74 serializer: S,
75 ) -> Result<S::Ok, S::Error>
76 where
77 R: RealField,
78 S: Serializer,
79 DefaultAllocator: Allocator<ROWS, COLS>,
80 ROWS: DimName,
81 COLS: DimName,
82 {
83 use serde::ser::SerializeSeq;
84
85 let nrows = arr.nrows();
86 let mut outer_seq = serializer.serialize_seq(Some(nrows))?;
87 for row in arr.row_iter() {
88 let inner_seq: Vec<f64> = row
89 .iter()
90 .map(|el| nalgebra::try_convert(el.clone()).unwrap())
91 .collect();
92 outer_seq.serialize_element(&inner_seq)?;
93 }
94 outer_seq.end()
95 }
96
97 pub fn deserialize<'de, D, R: RealField, ROWS, COLS>(
102 deserializer: D,
103 ) -> Result<OMatrix<R, ROWS, COLS>, D::Error>
104 where
105 D: Deserializer<'de>,
106 DefaultAllocator: Allocator<ROWS, COLS>,
107 ROWS: DimName,
108 COLS: DimName,
109 {
110 let v = serde_json::Value::deserialize(deserializer)?;
112 let rows = v
113 .as_array()
114 .ok_or_else(|| serde::de::Error::custom("expected array"))?;
115
116 if rows.len() != ROWS::USIZE {
117 return Err(serde::de::Error::custom(format!(
118 "expected {} rows, found {}",
119 ROWS::USIZE,
120 rows.len()
121 )));
122 }
123
124 let mut values = Vec::<R>::with_capacity(3 * COLS::dim());
125 for (i, row_value) in rows.iter().enumerate() {
126 let row = row_value
127 .as_array()
128 .ok_or_else(|| serde::de::Error::custom("expected array"))?;
129
130 if row.len() != COLS::dim() {
131 return Err(serde::de::Error::custom(format!(
132 "in row {}, expected {} cols found {}",
133 i,
134 COLS::dim(),
135 row.len()
136 )));
137 }
138
139 for el_value in row {
140 let el = el_value
141 .as_f64()
142 .ok_or_else(|| serde::de::Error::custom("expected float"))?;
143 values.push(nalgebra::convert(el));
144 }
145 }
146
147 Ok(nalgebra::OMatrix::<R, ROWS, COLS>::from_row_slice(&values))
148 }
149}
150
151#[test]
152fn matrix3x4_roundtrip() {
153 #[derive(Debug, Serialize, Deserialize)]
154 pub struct Outer<R: RealField> {
155 #[serde(with = "array_of_arrays")]
156 pub(crate) inner: OMatrix<R, U3, U4>,
157 }
158
159 let orig: Outer<f64> = Outer {
160 inner: OMatrix::<f64, U3, U4>::from_row_slice(&[
161 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0,
162 ]),
163 };
164
165 let buf = serde_json::to_vec(&orig).unwrap();
166 println!("buf: {}", std::str::from_utf8(&buf).unwrap());
167 let loaded: Outer<f64> = serde_json::from_slice(&buf).unwrap();
168
169 approx::assert_abs_diff_eq!(orig.inner, loaded.inner, epsilon = 1e-32);
170}
171
172#[cfg(test)]
173use nalgebra::U1;
174
175#[test]
176fn matrix4x1_roundtrip() {
177 #[derive(Debug, Serialize, Deserialize)]
178 pub struct Outer<R: RealField> {
179 #[serde(with = "array_of_arrays")]
180 pub(crate) inner: OMatrix<R, U4, U1>,
181 }
182
183 let orig: Outer<f64> = Outer {
184 inner: OMatrix::<f64, U4, U1>::from_row_slice(&[1.0, 2.0, 3.0, 4.0]),
185 };
186
187 let buf = serde_json::to_vec(&orig).unwrap();
188 println!("buf: {}", std::str::from_utf8(&buf).unwrap());
189 let loaded: Outer<f64> = serde_json::from_slice(&buf).unwrap();
190
191 approx::assert_abs_diff_eq!(orig.inner, loaded.inner, epsilon = 1e-32);
192}