lib3mf_core/parser/
mesh_parser.rs1use crate::error::{Lib3mfError, Result};
2use crate::model::{ClippingMode, Mesh, Triangle, Vertex};
3use crate::parser::beamlattice_parser::parse_beam_lattice_content;
4use crate::parser::xml_parser::{XmlParser, get_attribute, get_attribute_f32, get_attribute_u32};
5use quick_xml::events::Event;
6use std::io::BufRead;
7
8pub fn parse_mesh<R: BufRead>(parser: &mut XmlParser<R>) -> Result<Mesh> {
9 let mut mesh = Mesh::default();
10
11 loop {
12 match parser.read_next_event()? {
13 Event::Start(e) => match e.name().as_ref() {
14 b"vertices" => parse_vertices(parser, &mut mesh)?,
15 b"triangles" => parse_triangles(parser, &mut mesh)?,
16 b"beamlattice" => {
17 let min_length = get_attribute_f32(&e, b"minlength").unwrap_or(0.0);
18 let precision = get_attribute_f32(&e, b"precision").unwrap_or(0.0);
19 let clipping_mode = if let Some(s) = get_attribute(&e, b"clippingmode") {
20 match s.as_ref() {
21 "inside" => ClippingMode::Inside,
22 "outside" => ClippingMode::Outside,
23 _ => ClippingMode::None,
24 }
25 } else {
26 ClippingMode::None
27 };
28
29 let lattice =
30 parse_beam_lattice_content(parser, min_length, precision, clipping_mode)?;
31 mesh.beam_lattice = Some(lattice);
32 }
33 _ => {} },
35 Event::End(e) if e.name().as_ref() == b"mesh" => break,
36 Event::Eof => {
37 return Err(Lib3mfError::Validation(
38 "Unexpected EOF in mesh".to_string(),
39 ));
40 }
41 _ => {}
42 }
43 }
44
45 Ok(mesh)
46}
47
48fn parse_vertices<R: BufRead>(parser: &mut XmlParser<R>, mesh: &mut Mesh) -> Result<()> {
49 loop {
50 match parser.read_next_event()? {
51 Event::Start(e) | Event::Empty(e) if e.name().as_ref() == b"vertex" => {
52 let x = get_attribute_f32(&e, b"x")?;
53 let y = get_attribute_f32(&e, b"y")?;
54 let z = get_attribute_f32(&e, b"z")?;
55 mesh.vertices.push(Vertex { x, y, z });
56 }
57 Event::End(e) if e.name().as_ref() == b"vertices" => break,
58 Event::Eof => {
59 return Err(Lib3mfError::Validation(
60 "Unexpected EOF in vertices".to_string(),
61 ));
62 }
63 _ => {}
64 }
65 }
66 Ok(())
67}
68
69fn parse_triangles<R: BufRead>(parser: &mut XmlParser<R>, mesh: &mut Mesh) -> Result<()> {
70 loop {
71 match parser.read_next_event()? {
72 Event::Start(e) | Event::Empty(e) if e.name().as_ref() == b"triangle" => {
73 let v1 = get_attribute_u32(&e, b"v1")?;
74 let v2 = get_attribute_u32(&e, b"v2")?;
75 let v3 = get_attribute_u32(&e, b"v3")?;
76 let p1 = get_attribute_u32(&e, b"p1").ok();
77 let p2 = get_attribute_u32(&e, b"p2").ok();
78 let p3 = get_attribute_u32(&e, b"p3").ok();
79 let pid = get_attribute_u32(&e, b"pid").ok();
80
81 mesh.triangles.push(Triangle {
82 v1,
83 v2,
84 v3,
85 p1,
86 p2,
87 p3,
88 pid,
89 });
90 }
91 Event::End(e) if e.name().as_ref() == b"triangles" => break,
92 Event::Eof => {
93 return Err(Lib3mfError::Validation(
94 "Unexpected EOF in triangles".to_string(),
95 ));
96 }
97 _ => {}
98 }
99 }
100 Ok(())
101}