1pub mod csv;
13pub mod e57_format;
14pub mod las_format;
15pub mod pcd;
16pub mod ply;
17pub mod text;
18
19pub use csv::{read_csv, read_poses};
20pub use e57_format::{read_e57, write_e57};
21pub use las_format::{read_las, write_las};
22pub use pcd::{read_pcd, write_pcd};
23pub use ply::{read_ply, write_ply};
24pub use text::{read_text, write_text};
25
26use std::path::Path;
27
28use rigidity_core::PointCloud;
29
30pub fn read(path: &Path) -> Result<PointCloud, IoError> {
36 match extension(path).as_str() {
37 "ply" => read_ply(path),
38 "las" | "laz" => read_las(path),
39 "e57" => read_e57(path),
40 "pcd" => read_pcd(path),
41 "csv" | "txt" => read_text(path),
42 other => Err(IoError::UnknownFormat(other.to_owned())),
43 }
44}
45
46pub fn write(cloud: &PointCloud, path: &Path) -> Result<(), IoError> {
48 match extension(path).as_str() {
49 "ply" => write_ply(cloud, path),
50 "las" | "laz" => write_las(cloud, path),
51 "e57" => write_e57(cloud, path),
52 "pcd" => write_pcd(cloud, path),
53 "csv" | "txt" => write_text(cloud, path),
54 other => Err(IoError::UnknownFormat(other.to_owned())),
55 }
56}
57
58pub const READABLE: &[&str] = &["ply", "las", "laz", "e57", "pcd", "csv", "txt"];
60
61pub const WRITABLE: &[&str] = &["ply", "las", "laz", "e57", "pcd", "txt", "csv"];
68
69fn extension(path: &Path) -> String {
70 path.extension()
71 .and_then(|extension| extension.to_str())
72 .unwrap_or_default()
73 .to_ascii_lowercase()
74}
75
76#[derive(Debug, thiserror::Error)]
78pub enum IoError {
79 #[error("I/O error: {0}")]
81 Io(#[from] std::io::Error),
82 #[error("not a PLY file: the first line is not \"ply\"")]
84 NotPly,
85 #[error("PLY format \"{0}\" is not supported: need ascii or binary_little_endian")]
87 UnsupportedFormat(String),
88 #[error("malformed PLY header: {0}")]
90 BadHeader(String),
91 #[error("unknown PLY property type: \"{0}\"")]
93 UnknownPropertyType(String),
94 #[error("the vertex element is missing the x, y, z properties")]
96 MissingCoordinates,
97 #[error("list properties inside the vertex element are not supported")]
99 ListInVertex,
100 #[error("the first PLY element must be vertex, found \"{0}\"")]
102 VertexNotFirst(String),
103 #[error("truncated data: need {expected} bytes, {actual} available")]
105 Truncated {
106 expected: usize,
108 actual: usize,
110 },
111 #[error("could not parse the number \"{0}\"")]
113 BadNumber(String),
114 #[error("LAS error: {0}")]
116 Las(String),
117 #[error("E57 error: {0}")]
119 E57(String),
120 #[error("malformed PCD header: {0}")]
122 BadPcd(String),
123 #[error("unsupported PCD data: \"{0}\"")]
125 UnsupportedPcd(String),
126 #[error("unknown format: \"{0}\"")]
132 UnknownFormat(String),
133 #[error(transparent)]
135 Cloud(#[from] rigidity_core::CloudError),
136}