1mod decoder;
33pub mod ifcx;
34pub mod lighting;
35mod model;
36mod properties;
37mod resolver;
38mod scanner;
39mod spatial;
40mod tokenizer;
41mod units;
42
43pub use decoder::EntityDecoder;
44pub use ifcx::{is_ifcx_format, IfcxGeometry, IfcxModel};
45pub use lighting::{export_to_json, extract_lighting_data, LightFixtureData, LightingExport};
46pub use model::ParsedModel;
47pub use scanner::EntityScanner;
48pub use tokenizer::{parse_entity, Token};
49
50use bimifc_model::{IfcModel, IfcParser, ProgressCallback, Result};
51use std::sync::Arc;
52
53#[derive(Default)]
58pub struct StepParser {
59 pub build_spatial_tree: bool,
61 pub extract_properties: bool,
63}
64
65impl StepParser {
66 pub fn new() -> Self {
68 Self {
69 build_spatial_tree: true,
70 extract_properties: true,
71 }
72 }
73
74 pub fn geometry_only() -> Self {
76 Self {
77 build_spatial_tree: false,
78 extract_properties: false,
79 }
80 }
81
82 pub fn with_spatial_tree(mut self, enabled: bool) -> Self {
84 self.build_spatial_tree = enabled;
85 self
86 }
87
88 pub fn with_properties(mut self, enabled: bool) -> Self {
90 self.extract_properties = enabled;
91 self
92 }
93}
94
95impl IfcParser for StepParser {
96 fn parse(&self, content: &str) -> Result<Arc<dyn IfcModel>> {
97 ParsedModel::parse(content, self.build_spatial_tree, self.extract_properties)
98 .map(|m| Arc::new(m) as Arc<dyn IfcModel>)
99 }
100
101 fn parse_with_progress(
102 &self,
103 content: &str,
104 on_progress: ProgressCallback,
105 ) -> Result<Arc<dyn IfcModel>> {
106 ParsedModel::parse_with_progress(
107 content,
108 self.build_spatial_tree,
109 self.extract_properties,
110 on_progress,
111 )
112 .map(|m| Arc::new(m) as Arc<dyn IfcModel>)
113 }
114}
115
116pub fn parse(content: &str) -> Result<Arc<dyn IfcModel>> {
118 StepParser::new().parse(content)
119}
120
121pub fn parse_with_progress(
123 content: &str,
124 on_progress: impl Fn(&str, f32) + Send + 'static,
125) -> Result<Arc<dyn IfcModel>> {
126 StepParser::new().parse_with_progress(content, Box::new(on_progress))
127}
128
129pub fn parse_auto(content: &str) -> Result<Arc<dyn IfcModel>> {
134 if is_ifcx_format(content) {
135 IfcxModel::parse(content).map(|m| Arc::new(m) as Arc<dyn IfcModel>)
136 } else {
137 parse(content)
138 }
139}
140
141#[derive(Default)]
143pub struct UnifiedParser {
144 pub step_settings: StepParser,
146}
147
148impl UnifiedParser {
149 pub fn new() -> Self {
150 Self::default()
151 }
152}
153
154impl IfcParser for UnifiedParser {
155 fn parse(&self, content: &str) -> Result<Arc<dyn IfcModel>> {
156 if is_ifcx_format(content) {
157 IfcxModel::parse(content).map(|m| Arc::new(m) as Arc<dyn IfcModel>)
158 } else {
159 self.step_settings.parse(content)
160 }
161 }
162
163 fn parse_with_progress(
164 &self,
165 content: &str,
166 on_progress: ProgressCallback,
167 ) -> Result<Arc<dyn IfcModel>> {
168 if is_ifcx_format(content) {
169 on_progress("Parsing IFCX JSON", 0.0);
170 let result = IfcxModel::parse(content).map(|m| Arc::new(m) as Arc<dyn IfcModel>);
171 on_progress("Done", 1.0);
172 result
173 } else {
174 self.step_settings.parse_with_progress(content, on_progress)
175 }
176 }
177}