@@ -11,10 +11,11 @@ use splashsurf_lib::mesh::TriMesh3d;
1111use splashsurf_lib:: nalgebra:: Vector3 ;
1212use splashsurf_lib:: Real ;
1313
14+ /// Tries to read particle positions from the PLY file at the given path
1415pub 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+ /// ```
5874pub 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