lib3mf_core/parser/
boolean_parser.rs1use crate::error::{Lib3mfError, Result};
2use crate::model::{BooleanOperation, BooleanOperationType, BooleanShape, ResourceId};
3use crate::parser::component_parser::parse_transform;
4use crate::parser::xml_parser::{XmlParser, get_attribute, get_attribute_u32};
5use quick_xml::events::Event;
6use std::io::BufRead;
7
8pub fn parse_boolean_shape<R: BufRead>(
19 parser: &mut XmlParser<R>,
20 base_object_id: ResourceId,
21 base_transform: glam::Mat4,
22 base_path: Option<String>,
23) -> Result<BooleanShape> {
24 let mut operations = Vec::new();
25
26 loop {
28 match parser.read_next_event()? {
29 Event::Start(e) | Event::Empty(e) => {
30 let local_name = e.local_name();
31 if local_name.as_ref() == b"boolean" {
32 let operation = parse_boolean_operation(&e)?;
33 operations.push(operation);
34 }
35 }
36 Event::End(e) => {
37 let local_name = e.local_name();
38 if local_name.as_ref() == b"booleanshape" {
39 break;
40 }
41 }
42 Event::Eof => {
43 return Err(Lib3mfError::Validation(
44 "Unexpected EOF in booleanshape".to_string(),
45 ));
46 }
47 _ => {}
48 }
49 }
50
51 Ok(BooleanShape {
52 base_object_id,
53 base_transform,
54 base_path,
55 operations,
56 })
57}
58
59fn parse_boolean_operation(elem: &quick_xml::events::BytesStart) -> Result<BooleanOperation> {
61 let object_id = ResourceId(get_attribute_u32(elem, b"objectid")?);
62
63 let operation_type = if let Some(op_str) = get_attribute(elem, b"operation") {
65 match op_str.as_ref() {
66 "union" => BooleanOperationType::Union,
67 "difference" => BooleanOperationType::Difference,
68 "intersection" => BooleanOperationType::Intersection,
69 _ => BooleanOperationType::Union, }
71 } else {
72 BooleanOperationType::Union
73 };
74
75 let transform = if let Some(s) = get_attribute(elem, b"transform") {
76 parse_transform(&s)?
77 } else {
78 glam::Mat4::IDENTITY
79 };
80
81 let path = get_attribute(elem, b"path")
82 .or_else(|| get_attribute(elem, b"p:path"))
83 .map(|s| s.into_owned());
84
85 Ok(BooleanOperation {
86 operation_type,
87 object_id,
88 transform,
89 path,
90 })
91}