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