lib3mf_core/parser/
beamlattice_parser.rs1use crate::error::{Lib3mfError, Result};
2use crate::model::{Beam, BeamLattice, BeamSet, CapMode, ClippingMode};
3use crate::parser::xml_parser::{XmlParser, get_attribute, get_attribute_f32, get_attribute_u32};
4use quick_xml::events::Event;
5use std::io::BufRead;
6pub fn parse_beam_lattice_content<R: BufRead>(
13 parser: &mut XmlParser<R>,
14 min_length: f32,
15 precision: f32,
16 clipping_mode: ClippingMode,
17) -> Result<BeamLattice> {
18 let mut beams = Vec::new();
19 let mut beam_sets = Vec::new();
20
21 loop {
22 match parser.read_next_event()? {
23 Event::Start(e) => match e.name().as_ref() {
24 b"beams" => {
25 beams = parse_beams(parser)?;
26 }
27 b"beamsets" => {
28 beam_sets = parse_beam_sets(parser)?;
29 }
30 _ => {}
31 },
32 Event::End(e) if e.name().as_ref() == b"beamlattice" => break,
33 Event::Eof => {
34 return Err(Lib3mfError::Validation(
35 "Unexpected EOF in beamlattice".to_string(),
36 ));
37 }
38 _ => {}
39 }
40 }
41
42 Ok(BeamLattice {
43 min_length,
44 precision,
45 clipping_mode,
46 beams,
47 beam_sets,
48 })
49}
50
51fn parse_beams<R: BufRead>(parser: &mut XmlParser<R>) -> Result<Vec<Beam>> {
52 let mut beams = Vec::new();
53 loop {
54 match parser.read_next_event()? {
55 Event::Start(e) | Event::Empty(e) if e.name().as_ref() == b"beam" => {
56 let v1 = get_attribute_u32(&e, b"v1")?;
57 let v2 = get_attribute_u32(&e, b"v2")?;
58 let r1 = get_attribute_f32(&e, b"r1")?;
59 let r2 = get_attribute_f32(&e, b"r2").unwrap_or(r1);
60 let p1 = get_attribute_u32(&e, b"p1").ok();
61 let p2 = get_attribute_u32(&e, b"p2").ok();
62
63 let cap_mode = if let Some(s) = get_attribute(&e, b"cap") {
64 match s.as_ref() {
65 "sphere" => CapMode::Sphere,
66 "hemisphere" => CapMode::Hemisphere,
67 "butt" => CapMode::Butt,
68 _ => CapMode::Sphere,
69 }
70 } else {
71 CapMode::Sphere
72 };
73
74 beams.push(Beam {
75 v1,
76 v2,
77 r1,
78 r2,
79 p1,
80 p2,
81 cap_mode,
82 });
83 }
84 Event::End(e) if e.name().as_ref() == b"beams" => break,
85 Event::Eof => {
86 return Err(Lib3mfError::Validation(
87 "Unexpected EOF in beams".to_string(),
88 ));
89 }
90 _ => {}
91 }
92 }
93 Ok(beams)
94}
95
96fn parse_beam_sets<R: BufRead>(parser: &mut XmlParser<R>) -> Result<Vec<BeamSet>> {
97 let mut sets = Vec::new();
98 loop {
99 let event = parser.read_next_event()?;
100 match event {
101 Event::Start(e) if e.name().as_ref() == b"beamset" => {
102 let name = get_attribute(&e, b"name").map(|s| s.into_owned());
103 let identifier = get_attribute(&e, b"identifier").map(|s| s.into_owned());
104 let refs = parse_refs(parser)?;
105 sets.push(BeamSet {
106 name,
107 identifier,
108 refs,
109 });
110 }
111 Event::Empty(e) if e.name().as_ref() == b"beamset" => {
112 let name = get_attribute(&e, b"name").map(|s| s.into_owned());
113 let identifier = get_attribute(&e, b"identifier").map(|s| s.into_owned());
114 sets.push(BeamSet {
115 name,
116 identifier,
117 refs: Vec::new(),
118 });
119 }
120 Event::End(e) if e.name().as_ref() == b"beamsets" => break,
121 Event::Eof => {
122 return Err(Lib3mfError::Validation(
123 "Unexpected EOF in beamsets".to_string(),
124 ));
125 }
126 _ => {}
127 }
128 }
129 Ok(sets)
130}
131
132fn parse_refs<R: BufRead>(parser: &mut XmlParser<R>) -> Result<Vec<u32>> {
133 let mut refs = Vec::new();
134 loop {
135 match parser.read_next_event()? {
136 Event::Start(e) | Event::Empty(e) if e.name().as_ref() == b"ref" => {
137 let idx = get_attribute_u32(&e, b"index")?;
138 refs.push(idx);
139 }
140 Event::End(e) if e.name().as_ref() == b"beamset" => break,
141 Event::Eof => {
142 return Err(Lib3mfError::Validation(
143 "Unexpected EOF in beamset".to_string(),
144 ));
145 }
146 _ => {}
147 }
148 }
149 Ok(refs)
150}