@@ -356,20 +356,21 @@ impl AttributeStorage {
356356mod parser {
357357 use nom:: branch:: alt;
358358 use nom:: bytes:: streaming:: { tag, take} ;
359- use nom:: combinator:: { map , map_opt, map_res, not, recognize, value, verify} ;
360- use nom:: multi:: count;
359+ use nom:: combinator:: { map_opt, map_res, not, recognize, value, verify} ;
360+ use nom:: multi:: { count, fold } ;
361361 use nom:: number:: complete as number;
362362 use nom:: { IResult , Parser } ;
363363
364364 use super :: error:: { bgeo_error, make_bgeo_error, BgeoParserError , BgeoParserErrorKind } ;
365365 use super :: { AttribDefinition , AttributeStorage , BgeoAttributeType , BgeoFile , BgeoHeader } ;
366366
367- pub fn bgeo_parser < ' a > ( ) -> impl Parser < & ' a [ u8 ] , BgeoFile , BgeoParserError < & ' a [ u8 ] > > {
367+ pub fn bgeo_parser < ' a > (
368+ ) -> impl Parser < & ' a [ u8 ] , Output = BgeoFile , Error = BgeoParserError < & ' a [ u8 ] > > {
368369 move |input : & ' a [ u8 ] | -> IResult < & ' a [ u8 ] , BgeoFile , BgeoParserError < & ' a [ u8 ] > > {
369370 // Parse file header and attribute definitions
370371 let ( input, header) = parse_header ( input) ?;
371372 let ( input, named_attribute_definitions) =
372- count ( parse_attr_def, header. num_point_attrib as usize ) ( input) ?;
373+ count ( parse_attr_def, header. num_point_attrib as usize ) . parse ( input) ?;
373374
374375 // Add the "position" attribute which should always be present
375376 let special_attribute_definitions = {
@@ -418,12 +419,12 @@ mod parser {
418419
419420 /// Parses the BGEO format magic bytes
420421 fn parse_magic_bytes ( input : & [ u8 ] ) -> IResult < & [ u8 ] , & [ u8 ] , BgeoParserError < & [ u8 ] > > {
421- tag ( "Bgeo" ) ( input)
422+ tag ( "Bgeo" ) . parse ( input)
422423 }
423424
424425 /// Parses the (unsupported) new BGEO format magic bytes
425426 fn parse_new_magic_bytes ( input : & [ u8 ] ) -> IResult < & [ u8 ] , & [ u8 ] , BgeoParserError < & [ u8 ] > > {
426- tag ( [ 0x7f , 0x4e , 0x53 , 0x4a ] ) ( input)
427+ tag ( [ 0x7f , 0x4e , 0x53 , 0x4a ] . as_slice ( ) ) . parse ( input)
427428 }
428429
429430 /// Parses and validates the magic bytes of a BGEO file header
@@ -442,7 +443,8 @@ mod parser {
442443 BgeoParserErrorKind :: UnsupportedFormatVersion ,
443444 value ( "" . as_bytes ( ) , not ( parse_new_magic_bytes) ) ,
444445 ) ) ,
445- ) ) ( input)
446+ ) )
447+ . parse ( input)
446448 }
447449
448450 #[ test]
@@ -528,7 +530,8 @@ mod parser {
528530 let ( input, name_length) = number:: be_u16 ( input) ?;
529531 let ( input, name) = map_res ( take ( name_length as usize ) , |input : & [ u8 ] | {
530532 std:: str:: from_utf8 ( input) . map_err ( |_| BgeoParserErrorKind :: InvalidAttributeName )
531- } ) ( input) ?;
533+ } )
534+ . parse ( input) ?;
532535
533536 let ( input, size) = number:: be_u16 ( input) ?;
534537 let ( input, attr_type) = bgeo_error (
@@ -538,7 +541,7 @@ mod parser {
538541
539542 match attr_type {
540543 BgeoAttributeType :: Float | BgeoAttributeType :: Int | BgeoAttributeType :: Vector => {
541- let ( input, default_values) = count ( number:: be_i32, size as usize ) ( input) ?;
544+ let ( input, default_values) = count ( number:: be_i32, size as usize ) . parse ( input) ?;
542545
543546 let attr = AttribDefinition {
544547 name : name. to_string ( ) ,
@@ -585,12 +588,12 @@ mod parser {
585588 let mut input = input;
586589
587590 // Get the parser functions
588- let mut parser_funs: Vec < _ > = parsers. iter_mut ( ) . map ( |p| p. parser ( ) ) . collect ( ) ;
591+ // let mut parser_funs: Vec<_> = parsers.iter_mut().map(|p| p.parser()).collect();
589592 // For each point...
590593 for _ in 0 ..num_points {
591594 // ...apply all parsers in succession
592- for parser in & mut parser_funs {
593- let ( i, _) = ( parser) . parse ( input) ?;
595+ for parser in parsers . iter_mut ( ) {
596+ let ( i, _) = parser. parse ( input) ?;
594597 input = i;
595598 }
596599 }
@@ -682,58 +685,39 @@ mod parser {
682685 Self { attrib, storage }
683686 }
684687
685- /// Returns a boxed parser for this attribute
686- fn parser < ' a , ' b > (
687- & ' b mut self ,
688- ) -> Box < dyn Parser < & ' a [ u8 ] , ( ) , BgeoParserError < & ' a [ u8 ] > > + ' b > {
688+ fn parse < ' a > (
689+ & mut self ,
690+ input : & ' a [ u8 ] ,
691+ ) -> IResult < & ' a [ u8 ] , ( ) , BgeoParserError < & ' a [ u8 ] > > {
689692 match self . attrib . attr_type {
690693 BgeoAttributeType :: Int => {
691694 let storage = self . storage . as_int_mut ( ) ;
692- let size = self . attrib . size ;
693- Box :: new (
694- move |input : & ' a [ u8 ] | -> IResult < & ' a [ u8 ] , ( ) , BgeoParserError < & ' a [ u8 ] > > {
695- let ( input, _) = count (
696- map ( number:: be_i32, |val| {
697- //println!("i32: {}", val);
698- storage. push ( val) ;
699- } ) ,
700- size,
701- ) ( input) ?;
702- Ok ( ( input, ( ) ) )
703- } ,
704- )
695+ map_res ( number:: be_i32, |val| {
696+ storage. push ( val) ;
697+ Ok ( ( ) )
698+ } )
699+ . parse ( input)
705700 }
706701 BgeoAttributeType :: Float => {
707702 let storage = self . storage . as_float_mut ( ) ;
708- let size = self . attrib . size ;
709- Box :: new (
710- move |input : & ' a [ u8 ] | -> IResult < & ' a [ u8 ] , ( ) , BgeoParserError < & ' a [ u8 ] > > {
711- let ( input, _) = count (
712- map ( number:: be_f32, |val| {
713- //println!("f32: {}", val);
714- storage. push ( val) ;
715- } ) ,
716- size,
717- ) ( input) ?;
718- Ok ( ( input, ( ) ) )
719- } ,
720- )
703+ map_res ( number:: be_f32, |val| {
704+ storage. push ( val) ;
705+ Ok ( ( ) )
706+ } )
707+ . parse ( input)
721708 }
722709 BgeoAttributeType :: Vector => {
723710 let storage = self . storage . as_vec_mut ( ) ;
724711 let size = self . attrib . size ;
725- Box :: new (
726- move |input : & ' a [ u8 ] | -> IResult < & ' a [ u8 ] , ( ) , BgeoParserError < & ' a [ u8 ] > > {
727- let ( input, _) = count (
728- map ( number:: be_f32, |val| {
729- //println!("vec: {}", val);
730- storage. push ( val) ;
731- } ) ,
732- size,
733- ) ( input) ?;
734- Ok ( ( input, ( ) ) )
712+ fold (
713+ size,
714+ number:: be_f32,
715+ || ( ) ,
716+ |_, val| {
717+ storage. push ( val) ;
735718 } ,
736719 )
720+ . parse ( input)
737721 }
738722 _ => panic ! ( "Unsupported attribute type" ) ,
739723 }
@@ -859,7 +843,7 @@ mod error {
859843 mut f : F ,
860844 ) -> impl FnMut ( I ) -> IResult < I , O , BgeoParserError < I > >
861845 where
862- F : Parser < I , O , BgeoParserError < I > > ,
846+ F : Parser < I , Output = O , Error = BgeoParserError < I > > ,
863847 {
864848 use nom:: Err ;
865849 move |i : I | match f. parse ( i. clone ( ) ) {
@@ -888,6 +872,68 @@ fn test_bgeo_read_dam_break() {
888872 assert ! ( enclosing. contains_aabb( & aabb) ) ;
889873}
890874
875+ #[ test]
876+ fn test_bgeo_read_dam_break_attributes ( ) {
877+ let input_file = Path :: new ( "../data/dam_break_frame_9_6859_particles.bgeo" ) ;
878+
879+ let bgeo_file = load_bgeo_file ( input_file) . unwrap ( ) ;
880+
881+ let particles = particles_from_bgeo_file :: < f32 > ( & bgeo_file) . unwrap ( ) ;
882+
883+ assert_eq ! ( particles. len( ) , 6859 ) ;
884+
885+ eprintln ! ( "{:?}" , bgeo_file. attribute_definitions) ;
886+ assert_eq ! ( bgeo_file. attribute_definitions. len( ) , 3 ) ;
887+ assert_eq ! ( bgeo_file. attribute_data. len( ) , 3 ) ;
888+
889+ use crate :: Aabb3d ;
890+ let aabb = Aabb3d :: from_points ( & particles) ;
891+ let enclosing = Aabb3d :: new (
892+ Vector3 :: new ( -2.0 , 0.03 , -0.8 ) ,
893+ Vector3 :: new ( -0.3 , 0.7 , 0.72 ) ,
894+ ) ;
895+
896+ assert ! ( enclosing. contains_aabb( & aabb) ) ;
897+
898+ let attribs = attributes_from_bgeo_file :: < f32 > (
899+ & bgeo_file,
900+ & [
901+ "id" . to_string ( ) ,
902+ "density" . to_string ( ) ,
903+ "velocity" . to_string ( ) ,
904+ ] ,
905+ )
906+ . unwrap ( ) ;
907+
908+ assert_eq ! ( attribs. len( ) , 3 ) ;
909+
910+ assert ! ( matches!( attribs[ 0 ] . data, AttributeData :: ScalarU64 ( _) ) ) ;
911+ assert ! ( matches!( attribs[ 1 ] . data, AttributeData :: ScalarReal ( _) ) ) ;
912+ assert ! ( matches!( attribs[ 2 ] . data, AttributeData :: Vector3Real ( _) ) ) ;
913+
914+ if let AttributeData :: ScalarU64 ( ids) = & attribs[ 0 ] . data {
915+ assert_eq ! ( ids. len( ) , particles. len( ) ) ;
916+ assert_eq ! ( ids[ 0 ] , 30 ) ;
917+ assert_eq ! ( ids[ 1 ] , 11 ) ;
918+ assert_eq ! ( ids[ 2 ] , 12 ) ;
919+ }
920+
921+ if let AttributeData :: ScalarReal ( densities) = & attribs[ 1 ] . data {
922+ assert_eq ! ( densities. len( ) , particles. len( ) ) ;
923+ assert_eq ! ( densities[ 0 ] , 1000.1286 ) ;
924+ assert_eq ! ( densities[ 1 ] , 1001.53424 ) ;
925+ assert_eq ! ( densities[ 2 ] , 1001.6626 ) ;
926+ }
927+
928+ if let AttributeData :: Vector3Real ( velocities) = & attribs[ 2 ] . data {
929+ assert_eq ! ( velocities. len( ) , particles. len( ) ) ;
930+ assert_eq ! (
931+ velocities[ 0 ] ,
932+ Vector3 :: new( 0.3670507 , -0.41762838 , 0.42659923 )
933+ ) ;
934+ }
935+ }
936+
891937#[ test]
892938fn test_bgeo_write_dam_break ( ) {
893939 let input_file = Path :: new ( "../data/dam_break_frame_9_6859_particles.bgeo" ) ;
0 commit comments