rust_3d/
compressed_point_cloud_3d.rs1use num::traits::{PrimInt, Unsigned};
26
27use crate::*;
28
29#[derive(Debug, Clone, PartialEq, PartialOrd)]
32pub struct CompressedPointCloud3D<T>
34where
35 T: Unsigned + PrimInt,
36{
37 pub start: Point3D,
38 pub unitsizex: f64,
39 pub unitsizey: f64,
40 pub unitsizez: f64,
41 pub data: Vec<CompressedPoint3D<T>>,
42}
43
44impl<T> CompressedPointCloud3D<T>
45where
46 T: Unsigned + PrimInt,
47{
48 pub fn compress<P>(pc: &PointCloud3D<P>) -> Result<CompressedPointCloud3D<T>>
50 where
51 P: Is3D,
52 {
53 let bb = pc.bounding_box_maybe()?;
54
55 let rangex = (bb.max_p().x - bb.min_p().x).abs();
56 let rangey = (bb.max_p().y - bb.min_p().y).abs();
57 let rangez = (bb.max_p().z - bb.min_p().z).abs();
58
59 let maxval = T::max_value()
60 .to_f64()
61 .ok_or(ErrorKind::NumberConversionError)?;
62 let unitsizex = rangex / maxval;
63 let unitsizey = rangey / maxval;
64 let unitsizez = rangez / maxval;
65
66 let mut data = Vec::new();
67
68 for p in &pc.data {
69 let distx = p.x() - bb.min_p().x;
70 let disty = p.y() - bb.min_p().y;
71 let distz = p.z() - bb.min_p().z;
72
73 let unitsx = T::from(distx / unitsizex).ok_or(ErrorKind::NumberConversionError)?;
74 let unitsy = T::from(disty / unitsizey).ok_or(ErrorKind::NumberConversionError)?;
75 let unitsz = T::from(distz / unitsizez).ok_or(ErrorKind::NumberConversionError)?;
76
77 data.push(CompressedPoint3D {
78 unitsx,
79 unitsy,
80 unitsz,
81 })
82 }
83 Ok(CompressedPointCloud3D::<T> {
84 start: bb.min_p(),
85 unitsizex,
86 unitsizey,
87 unitsizez,
88 data,
89 })
90 }
91
92 pub fn decompress<P>(&self) -> PointCloud3D<P>
94 where
95 P: IsBuildable3D,
96 {
97 let mut pc = PointCloud3D::new();
98
99 for p in &self.data {
100 if let (Some(unitsxf), Some(unitsyf), Some(unitszf)) =
101 (p.unitsx.to_f64(), p.unitsy.to_f64(), p.unitsz.to_f64())
102 {
103 pc.push(P::new(
104 self.start.x + (self.unitsizex * unitsxf),
105 self.start.y + (self.unitsizey * unitsyf),
106 self.start.z + (self.unitsizez * unitszf),
107 ));
108 }
109 }
110 pc
111 }
112}