1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
//! Legacy Entity Registry
//!
//! Maps deprecated IFC2x3/IFC4 entities (removed in IFC4x3) to their IFC4x3 equivalents.
//! This allows parsing older IFC files without maintaining full multi-schema support.
use crate::generated::IfcType;
/// Information about a legacy entity
#[derive(Debug, Clone, Copy)]
pub struct LegacyEntityInfo {
/// The IFC4x3 base type this legacy entity maps to
pub base_type: IfcType,
/// Whether this entity typically has geometry
pub has_geometry: bool,
}
/// Map legacy entity name (uppercase) to its IFC4x3 equivalent
pub fn get_legacy_entity_info(entity_name: &str) -> Option<LegacyEntityInfo> {
match entity_name {
// === IFC4 entities removed in IFC4x3 ===
// Style entities
"IFCPRESENTATIONSTYLEASSIGNMENT" => Some(LegacyEntityInfo {
base_type: IfcType::IfcPresentationStyle,
has_geometry: false,
}),
// StandardCase variants (removed, use base type)
"IFCBEAMSTANDARDCASE" => Some(LegacyEntityInfo {
base_type: IfcType::IfcBeam,
has_geometry: true,
}),
"IFCCOLUMNSTANDARDCASE" => Some(LegacyEntityInfo {
base_type: IfcType::IfcColumn,
has_geometry: true,
}),
"IFCMEMBERSTANDARDCASE" => Some(LegacyEntityInfo {
base_type: IfcType::IfcMember,
has_geometry: true,
}),
"IFCPLATESTANDARDCASE" => Some(LegacyEntityInfo {
base_type: IfcType::IfcPlate,
has_geometry: true,
}),
"IFCSLABSTANDARDCASE" => Some(LegacyEntityInfo {
base_type: IfcType::IfcSlab,
has_geometry: true,
}),
"IFCDOORSTANDARDCASE" => Some(LegacyEntityInfo {
base_type: IfcType::IfcDoor,
has_geometry: true,
}),
"IFCWINDOWSTANDARDCASE" => Some(LegacyEntityInfo {
base_type: IfcType::IfcWindow,
has_geometry: true,
}),
"IFCOPENINGSTANDARDCASE" => Some(LegacyEntityInfo {
base_type: IfcType::IfcOpeningElement,
has_geometry: true,
}),
// ElementedCase variants
"IFCSLABELEMENTEDCASE" => Some(LegacyEntityInfo {
base_type: IfcType::IfcSlab,
has_geometry: true,
}),
"IFCWALLELEMENTEDCASE" => Some(LegacyEntityInfo {
base_type: IfcType::IfcWall,
has_geometry: true,
}),
// Style entities (replaced by Type)
"IFCDOORSTYLE" => Some(LegacyEntityInfo {
base_type: IfcType::IfcDoorType,
has_geometry: false,
}),
"IFCWINDOWSTYLE" => Some(LegacyEntityInfo {
base_type: IfcType::IfcWindowType,
has_geometry: false,
}),
// Deprecated generic element
"IFCPROXY" => Some(LegacyEntityInfo {
base_type: IfcType::IfcBuildingElementProxy,
has_geometry: true,
}),
// Abstract bases (removed, but rarely used directly)
"IFCBUILDINGELEMENT" => Some(LegacyEntityInfo {
base_type: IfcType::IfcBuiltElement,
has_geometry: true,
}),
"IFCBUILDINGELEMENTTYPE" => Some(LegacyEntityInfo {
base_type: IfcType::IfcBuiltElementType,
has_geometry: false,
}),
// IFC2x3 names that have no IFC4x3 enum variant. They map to the
// closest modern equivalent; both carry geometry.
"IFCEQUIPMENTELEMENT" => Some(LegacyEntityInfo {
base_type: IfcType::IfcDistributionElement,
has_geometry: true,
}),
"IFCELECTRICALDISTRIBUTIONPOINT" => Some(LegacyEntityInfo {
base_type: IfcType::IfcDistributionElement,
has_geometry: true,
}),
// === IFC4.3 stratum subtypes (issue #860) ===
//
// The schema enum exposes the abstract base `IfcGeotechnicalStratum`
// but not the three concrete leaves (`IfcSolidStratum`,
// `IfcVoidStratum`, `IfcWaterStratum`). Without these, infrastructure
// models with terrain / soil layers (e.g. the user's UT_Tin_in_MGA_56
// fixture) come back as `IfcType::Unknown(...)` and
// `has_geometry_by_name` returns false — the geometry pipeline skips
// them silently. Map each subtype to the base so its `Body`
// representation (typically `IfcTriangulatedFaceSet`) is processed by
// the same code path as any other geotechnical product.
"IFCSOLIDSTRATUM" => Some(LegacyEntityInfo {
base_type: IfcType::IfcGeotechnicalStratum,
has_geometry: true,
}),
"IFCVOIDSTRATUM" => Some(LegacyEntityInfo {
base_type: IfcType::IfcGeotechnicalStratum,
has_geometry: true,
}),
"IFCWATERSTRATUM" => Some(LegacyEntityInfo {
base_type: IfcType::IfcGeotechnicalStratum,
has_geometry: true,
}),
_ => None,
}
}
/// Check if an entity name is a known legacy entity
pub fn is_legacy_entity(entity_name: &str) -> bool {
get_legacy_entity_info(entity_name).is_some()
}
/// Get the IFC4x3 base type for a legacy entity, or None if not legacy
pub fn map_legacy_to_base_type(entity_name: &str) -> Option<IfcType> {
get_legacy_entity_info(entity_name).map(|info| info.base_type)
}