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