1pub mod csv;
13pub mod e57_format;
14pub mod las_format;
15pub mod pcd;
16pub mod ply;
17
18pub use csv::{read_csv, read_poses};
19pub use e57_format::{read_e57, write_e57};
20pub use las_format::{read_las, write_las};
21pub use pcd::{read_pcd, write_pcd};
22pub use ply::{read_ply, write_ply};
23
24use std::path::Path;
25
26use rigidity_core::PointCloud;
27
28pub fn read(path: &Path) -> Result<PointCloud, IoError> {
34 match extension(path).as_str() {
35 "ply" => read_ply(path),
36 "las" | "laz" => read_las(path),
37 "e57" => read_e57(path),
38 "pcd" => read_pcd(path),
39 "csv" | "txt" => read_csv(path),
40 other => Err(IoError::UnknownFormat(other.to_owned())),
41 }
42}
43
44pub fn write(cloud: &PointCloud, path: &Path) -> Result<(), IoError> {
46 match extension(path).as_str() {
47 "ply" => write_ply(cloud, path),
48 "las" | "laz" => write_las(cloud, path),
49 "e57" => write_e57(cloud, path),
50 "pcd" => write_pcd(cloud, path),
51 other => Err(IoError::UnknownFormat(other.to_owned())),
52 }
53}
54
55pub const READABLE: &[&str] = &["ply", "las", "laz", "e57", "pcd", "csv", "txt"];
57
58pub const WRITABLE: &[&str] = &["ply", "las", "laz", "e57", "pcd"];
60
61fn extension(path: &Path) -> String {
62 path.extension()
63 .and_then(|extension| extension.to_str())
64 .unwrap_or_default()
65 .to_ascii_lowercase()
66}
67
68#[derive(Debug, thiserror::Error)]
70pub enum IoError {
71 #[error("I/O error: {0}")]
73 Io(#[from] std::io::Error),
74 #[error("not a PLY file: the first line is not \"ply\"")]
76 NotPly,
77 #[error("PLY format \"{0}\" is not supported: need ascii or binary_little_endian")]
79 UnsupportedFormat(String),
80 #[error("malformed PLY header: {0}")]
82 BadHeader(String),
83 #[error("unknown PLY property type: \"{0}\"")]
85 UnknownPropertyType(String),
86 #[error("the vertex element is missing the x, y, z properties")]
88 MissingCoordinates,
89 #[error("list properties inside the vertex element are not supported")]
91 ListInVertex,
92 #[error("the first PLY element must be vertex, found \"{0}\"")]
94 VertexNotFirst(String),
95 #[error("truncated data: need {expected} bytes, {actual} available")]
97 Truncated {
98 expected: usize,
100 actual: usize,
102 },
103 #[error("could not parse the number \"{0}\"")]
105 BadNumber(String),
106 #[error("LAS error: {0}")]
108 Las(String),
109 #[error("E57 error: {0}")]
111 E57(String),
112 #[error("malformed PCD header: {0}")]
114 BadPcd(String),
115 #[error("unsupported PCD data: \"{0}\"")]
117 UnsupportedPcd(String),
118 #[error("unknown format: \"{0}\"")]
124 UnknownFormat(String),
125 #[error(transparent)]
127 Cloud(#[from] rigidity_core::CloudError),
128}