11use std:: fs:: File ;
22use std:: io:: BufReader ;
3- use std:: ops:: AddAssign ;
43
54use :: e57:: { E57Reader , Point } ;
6- use ndarray:: { array , Array2 , Ix2 } ;
7- use numpy:: { IntoPyArray , PyArray } ;
5+ use ndarray:: Ix2 ;
6+ use numpy:: { PyArray } ;
87use pyo3:: prelude:: * ;
98
109/// Extracts the xml contents from an e57 file.
@@ -18,7 +17,7 @@ fn raw_xml(filepath: &str) -> PyResult<String> {
1817 Err ( e) => {
1918 return Err ( PyErr :: new :: < pyo3:: exceptions:: PyRuntimeError , _ > (
2019 e. to_string ( ) ,
21- ) )
20+ ) ) ;
2221 }
2322 } ;
2423 let xml_string = String :: from_utf8 ( xml. unwrap ( ) ) ?;
@@ -34,28 +33,44 @@ fn read_points<'py>(py: Python<'py>, filepath: &str) -> PyResult<&'py PyArray<f6
3433 Err ( e) => {
3534 return Err ( PyErr :: new :: < pyo3:: exceptions:: PyRuntimeError , _ > (
3635 e. to_string ( ) ,
37- ) )
36+ ) ) ;
3837 }
3938 } ;
4039 let pc = file. pointclouds ( ) ;
4140 let pc = pc. first ( ) . expect ( "files contain pointclouds" ) ;
42- let mut arr = Array2 :: zeros ( ( pc. records as usize , 3 ) ) ;
43-
41+ let ncols = 3 ;
42+ let mut vec = Vec :: with_capacity ( pc. records as usize * ncols) ;
43+ let mut nrows = 0 ;
4444 let iter = file
4545 . pointcloud ( pc)
4646 . expect ( "this file contains a pointcloud" ) ;
47- for ( i , p ) in iter. enumerate ( ) {
47+ for p in iter {
4848 let p = p. expect ( "Unable to read next point" ) ;
4949 let p = Point :: from_values ( p, & pc. prototype )
5050 . expect ( "failed to convert raw point to simple point" ) ;
5151 if let Some ( c) = p. cartesian {
52- let coordinates = array ! [ c. x, c. y, c. z] ;
53- let mut row = arr. row_mut ( i) ;
54- row. add_assign ( & coordinates) ;
52+ if let Some ( invalid) = p. cartesian_invalid {
53+ if invalid != 0 {
54+ continue ;
55+ }
56+ }
57+ vec. extend ( [ c. x , c. y , c. z ] ) ;
58+ nrows += 1
59+ } else if let Some ( s) = p. spherical {
60+ if let Some ( invalid) = p. spherical_invalid {
61+ if invalid != 0 {
62+ continue ;
63+ }
64+ }
65+ let cos_ele = f64:: cos ( s. elevation ) ;
66+ let x = s. range * cos_ele * f64:: cos ( s. azimuth ) ;
67+ let y = s. range * cos_ele * f64:: sin ( s. azimuth ) ;
68+ let z = s. range * f64:: sin ( s. elevation ) ;
69+ vec. extend ( [ x, y, z] ) ;
70+ nrows += 1
5571 }
5672 }
57-
58- Ok ( arr. into_pyarray ( py) )
73+ Ok ( PyArray :: from_vec ( py, vec) . reshape ( ( nrows, ncols) ) . unwrap ( ) )
5974}
6075
6176/// e57 pointcloud file reading.
0 commit comments