lib3mf_core/parser/
slice_parser.rs1use crate::error::{Lib3mfError, Result};
2use crate::model::{Polygon, Segment, Slice, SliceRef, SliceStack, Vertex2D};
3use crate::parser::xml_parser::{XmlParser, get_attribute, get_attribute_f32, get_attribute_u32};
4use quick_xml::events::Event;
5use std::borrow::Cow;
6use std::io::BufRead;
7
8pub fn parse_slice_stack_content<R: BufRead>(
11 parser: &mut XmlParser<R>,
12 id: crate::model::ResourceId,
13 z_bottom: f32,
14) -> Result<SliceStack> {
15 let mut slices = Vec::new();
16 let mut refs = Vec::new();
17
18 loop {
19 match parser.read_next_event()? {
20 Event::Start(e) => match e.local_name().as_ref() {
21 b"slice" => {
22 let z_top = get_attribute_f32(&e, b"ztop")?;
23 let slice = parse_slice(parser, z_top)?;
24 slices.push(slice);
25 }
26 b"sliceref" => {
27 let stack_id =
30 crate::model::ResourceId(get_attribute_u32(&e, b"slicestackid")?);
31 let path = get_attribute(&e, b"slicepath")
32 .map(|s: Cow<str>| s.into_owned())
33 .unwrap_or_default();
34 refs.push(SliceRef {
35 slice_stack_id: stack_id,
36 slice_path: path,
37 });
38 }
39 _ => {}
40 },
41 Event::Empty(e) => {
42 if e.local_name().as_ref() == b"sliceref" {
43 let stack_id =
44 crate::model::ResourceId(get_attribute_u32(&e, b"slicestackid")?);
45 let path = get_attribute(&e, b"slicepath")
46 .map(|s: Cow<str>| s.into_owned())
47 .unwrap_or_default();
48 refs.push(SliceRef {
49 slice_stack_id: stack_id,
50 slice_path: path,
51 });
52 }
53 }
54 Event::End(e) if e.local_name().as_ref() == b"slicestack" => break,
55 Event::Eof => {
56 return Err(Lib3mfError::Validation(
57 "Unexpected EOF in slicestack".to_string(),
58 ));
59 }
60 _ => {}
61 }
62 }
63
64 Ok(SliceStack {
65 id,
66 z_bottom,
67 slices,
68 refs,
69 })
70}
71
72fn parse_slice<R: BufRead>(parser: &mut XmlParser<R>, z_top: f32) -> Result<Slice> {
73 let mut vertices = Vec::new();
74 let mut polygons = Vec::new();
75
76 loop {
77 match parser.read_next_event()? {
78 Event::Start(e) => match e.local_name().as_ref() {
79 b"vertices" => {
80 vertices = parse_slice_vertices(parser)?;
81 }
82 b"polygon" => {
83 let start = get_attribute_u32(&e, b"start").unwrap_or(0);
87 let segments = parse_polygon_segments(parser)?;
88 polygons.push(Polygon {
89 start_segment: start,
90 segments,
91 });
92 }
93 _ => {}
94 },
95 Event::End(e) if e.local_name().as_ref() == b"slice" => break,
96 Event::Eof => {
97 return Err(Lib3mfError::Validation(
98 "Unexpected EOF in slice".to_string(),
99 ));
100 }
101 _ => {}
102 }
103 }
104
105 Ok(Slice {
106 z_top,
107 vertices,
108 polygons,
109 })
110}
111
112fn parse_slice_vertices<R: BufRead>(parser: &mut XmlParser<R>) -> Result<Vec<Vertex2D>> {
113 let mut vertices = Vec::new();
114 loop {
115 match parser.read_next_event()? {
116 Event::Start(e) | Event::Empty(e) if e.local_name().as_ref() == b"vertex" => {
117 let x = get_attribute_f32(&e, b"x")?;
118 let y = get_attribute_f32(&e, b"y")?;
119 vertices.push(Vertex2D { x, y });
120 }
121 Event::End(e) if e.local_name().as_ref() == b"vertices" => break,
122 Event::Eof => {
123 return Err(Lib3mfError::Validation(
124 "Unexpected EOF in slice vertices".to_string(),
125 ));
126 }
127 _ => {}
128 }
129 }
130 Ok(vertices)
131}
132
133fn parse_polygon_segments<R: BufRead>(parser: &mut XmlParser<R>) -> Result<Vec<Segment>> {
134 let mut segments = Vec::new();
135 loop {
136 match parser.read_next_event()? {
137 Event::Start(e) | Event::Empty(e) if e.local_name().as_ref() == b"segment" => {
138 let v2 = get_attribute_u32(&e, b"v2")?;
139 let p1 = get_attribute_u32(&e, b"p1").ok();
140 let p2 = get_attribute_u32(&e, b"p2").ok();
141 let pid = get_attribute_u32(&e, b"pid")
142 .map(crate::model::ResourceId)
143 .ok();
144
145 segments.push(Segment { v2, p1, p2, pid });
146 }
147 Event::End(e) if e.local_name().as_ref() == b"polygon" => break,
148 Event::Eof => {
149 return Err(Lib3mfError::Validation(
150 "Unexpected EOF in polygon segments".to_string(),
151 ));
152 }
153 _ => {}
154 }
155 }
156 Ok(segments)
157}