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::{
46 export_to_json, extract_lighting_data, goniometric_to_eulumdat, goniometric_to_ldt,
47 light_source_to_eulumdat, light_source_to_ldt, DistributionPlane, LightDistributionData,
48 LightFixtureData, LightSourceData, LightingExport,
49};
50pub use model::ParsedModel;
51pub use scanner::EntityScanner;
52pub use tokenizer::{parse_entity, Token};
53
54use bimifc_model::{IfcModel, IfcParser, ProgressCallback, Result};
55use std::sync::Arc;
56
57#[derive(Default)]
62pub struct StepParser {
63 pub build_spatial_tree: bool,
65 pub extract_properties: bool,
67}
68
69impl StepParser {
70 pub fn new() -> Self {
72 Self {
73 build_spatial_tree: true,
74 extract_properties: true,
75 }
76 }
77
78 pub fn geometry_only() -> Self {
80 Self {
81 build_spatial_tree: false,
82 extract_properties: false,
83 }
84 }
85
86 pub fn with_spatial_tree(mut self, enabled: bool) -> Self {
88 self.build_spatial_tree = enabled;
89 self
90 }
91
92 pub fn with_properties(mut self, enabled: bool) -> Self {
94 self.extract_properties = enabled;
95 self
96 }
97}
98
99impl IfcParser for StepParser {
100 fn parse(&self, content: &str) -> Result<Arc<dyn IfcModel>> {
101 ParsedModel::parse(content, self.build_spatial_tree, self.extract_properties)
102 .map(|m| Arc::new(m) as Arc<dyn IfcModel>)
103 }
104
105 fn parse_with_progress(
106 &self,
107 content: &str,
108 on_progress: ProgressCallback,
109 ) -> Result<Arc<dyn IfcModel>> {
110 ParsedModel::parse_with_progress(
111 content,
112 self.build_spatial_tree,
113 self.extract_properties,
114 on_progress,
115 )
116 .map(|m| Arc::new(m) as Arc<dyn IfcModel>)
117 }
118}
119
120pub fn parse(content: &str) -> Result<Arc<dyn IfcModel>> {
122 StepParser::new().parse(content)
123}
124
125pub fn parse_with_progress(
127 content: &str,
128 on_progress: impl Fn(&str, f32) + Send + 'static,
129) -> Result<Arc<dyn IfcModel>> {
130 StepParser::new().parse_with_progress(content, Box::new(on_progress))
131}
132
133pub fn parse_auto(content: &str) -> Result<Arc<dyn IfcModel>> {
138 if is_ifcx_format(content) {
139 IfcxModel::parse(content).map(|m| Arc::new(m) as Arc<dyn IfcModel>)
140 } else {
141 parse(content)
142 }
143}
144
145#[derive(Default)]
147pub struct UnifiedParser {
148 pub step_settings: StepParser,
150}
151
152impl UnifiedParser {
153 pub fn new() -> Self {
154 Self::default()
155 }
156}
157
158impl IfcParser for UnifiedParser {
159 fn parse(&self, content: &str) -> Result<Arc<dyn IfcModel>> {
160 if is_ifcx_format(content) {
161 IfcxModel::parse(content).map(|m| Arc::new(m) as Arc<dyn IfcModel>)
162 } else {
163 self.step_settings.parse(content)
164 }
165 }
166
167 fn parse_with_progress(
168 &self,
169 content: &str,
170 on_progress: ProgressCallback,
171 ) -> Result<Arc<dyn IfcModel>> {
172 if is_ifcx_format(content) {
173 on_progress("Parsing IFCX JSON", 0.0);
174 let result = IfcxModel::parse(content).map(|m| Arc::new(m) as Arc<dyn IfcModel>);
175 on_progress("Done", 1.0);
176 result
177 } else {
178 self.step_settings.parse_with_progress(content, on_progress)
179 }
180 }
181}