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