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