Skip to content

Commit 95b7daf

Browse files
committed
Make PLY readers more idomatic
1 parent aa8c44b commit 95b7daf

File tree

1 file changed

+45
-41
lines changed

1 file changed

+45
-41
lines changed

splashsurf/src/io/ply_format.rs

Lines changed: 45 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,11 @@ use splashsurf_lib::mesh::TriMesh3d;
1111
use splashsurf_lib::nalgebra::Vector3;
1212
use splashsurf_lib::Real;
1313

14+
/// Tries to read particle positions from the PLY file at the given path
1415
pub fn particles_from_ply<R: Real, P: AsRef<Path>>(
15-
ply_file: P,
16+
ply_path: P,
1617
) -> Result<Vec<Vector3<R>>, anyhow::Error> {
17-
let mut ply_file = std::fs::File::open(ply_file).unwrap();
18+
let mut ply_file = std::fs::File::open(ply_path).unwrap();
1819
let parser = ply::parser::Parser::<ply::ply::DefaultElement>::new();
1920

2021
let ply = parser
@@ -54,16 +55,31 @@ pub fn particles_from_ply<R: Real, P: AsRef<Path>>(
5455
Ok(particles)
5556
}
5657

57-
/// Tries to read a surface mesh from the VTK file at the given path
58+
/// Tries to read a surface mesh from the PLY file at the given path
59+
///
60+
/// The PLY file is expected to use the following structure which is used by Blender for export:
61+
/// ```text
62+
/// element vertex 24
63+
/// property float x
64+
/// property float y
65+
/// property float z
66+
/// property float nx
67+
/// property float ny
68+
/// property float nz
69+
/// property float s
70+
/// property float t
71+
/// element face 12
72+
/// property list uchar uint vertex_indices
73+
/// ```
5874
pub fn surface_mesh_from_ply<R: Real, P: AsRef<Path>>(
59-
ply_file: P,
75+
ply_path: P,
6076
) -> Result<MeshWithData<R, TriMesh3d<R>>, anyhow::Error> {
61-
let mut ply_file = std::fs::File::open(ply_file).unwrap();
77+
let mut ply_file = std::fs::File::open(ply_path).unwrap();
6278
let parser = ply::parser::Parser::<ply::ply::DefaultElement>::new();
6379

6480
let ply = parser
6581
.read_ply(&mut ply_file)
66-
.context("Failed to read PLY file")?;
82+
.context("Failed to parse PLY file")?;
6783
let vertices_normals = ply
6884
.payload
6985
.get("vertex")
@@ -90,7 +106,7 @@ pub fn surface_mesh_from_ply<R: Real, P: AsRef<Path>>(
90106
Property::Float(nx),
91107
Property::Float(ny),
92108
Property::Float(nz),
93-
) => (
109+
) => Ok((
94110
Vector3::new(
95111
R::from_f32(*x).unwrap(),
96112
R::from_f32(*y).unwrap(),
@@ -101,13 +117,11 @@ pub fn surface_mesh_from_ply<R: Real, P: AsRef<Path>>(
101117
R::from_f32(*ny).unwrap(),
102118
R::from_f32(*nz).unwrap(),
103119
),
104-
),
105-
_ => {
106-
return Err(anyhow!(
107-
"Vertex properties have wrong PLY data type (expected float)"
108-
))
109-
}
110-
};
120+
)),
121+
_ => Err(anyhow!(
122+
"Vertex properties have wrong PLY data type (expected float)"
123+
)),
124+
}?;
111125

112126
vertices.push(vertex);
113127
normals.push(normal);
@@ -121,35 +135,25 @@ pub fn surface_mesh_from_ply<R: Real, P: AsRef<Path>>(
121135
let triangles = faces
122136
.into_iter()
123137
.map(|e| {
124-
// This is as per what blender creates for a
125-
let indices = e.get("vertex_indices");
126-
if let Some(indices) = indices {
127-
if let Property::ListUInt(indices) = indices {
128-
if indices.len() == 3 {
129-
return Ok([
130-
indices[0] as usize,
131-
indices[1] as usize,
132-
indices[2] as usize,
133-
]);
134-
} else {
135-
return Err(anyhow!(
136-
"Invalid number of vertex indices per cell: {}",
137-
indices.len()
138-
));
139-
}
140-
} else {
141-
return Err(anyhow!(
142-
"Index properties have wrong PLY data type (expected uint)"
143-
));
144-
}
145-
} else {
146-
return Err(anyhow!(
147-
"Vertex properties have wrong PLY data type (expected uint)"
148-
));
138+
let indices = e
139+
.get("vertex_indices")
140+
.ok_or_else(|| anyhow!("A face is missing a 'vertex_indices' element"))?;
141+
match indices {
142+
Property::ListUInt(indices) if indices.len() == 3 => Ok([
143+
indices[0] as usize,
144+
indices[1] as usize,
145+
indices[2] as usize,
146+
]),
147+
Property::ListUInt(indices) => Err(anyhow!(
148+
"Invalid number of vertex indices per face: {} (expected 3)",
149+
indices.len()
150+
)),
151+
_ => Err(anyhow!(
152+
"Index properties have wrong PLY data type (expected uint)"
153+
)),
149154
}
150155
})
151-
.map(|e| e.unwrap())
152-
.collect();
156+
.collect::<Result<Vec<_>, _>>()?;
153157

154158
let normals = MeshAttribute::new("normals", AttributeData::Vector3Real(normals));
155159
Ok(MeshWithData::new(TriMesh3d {

0 commit comments

Comments
 (0)