Skip to main content

bimifc_model/
types.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
5//! Core types for IFC data representation
6//!
7//! This module defines the fundamental types used throughout the IFC parsing system.
8
9use serde::{Deserialize, Serialize};
10use std::fmt;
11use std::str::FromStr;
12
13/// Type-safe entity identifier
14///
15/// Wraps the raw IFC entity ID (e.g., #123 becomes EntityId(123))
16#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Serialize, Deserialize, Default)]
17pub struct EntityId(pub u32);
18
19impl fmt::Display for EntityId {
20    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
21        write!(f, "#{}", self.0)
22    }
23}
24
25impl From<u32> for EntityId {
26    fn from(id: u32) -> Self {
27        EntityId(id)
28    }
29}
30
31impl From<EntityId> for u32 {
32    fn from(id: EntityId) -> Self {
33        id.0
34    }
35}
36
37impl From<EntityId> for u64 {
38    fn from(id: EntityId) -> Self {
39        id.0 as u64
40    }
41}
42
43/// IFC entity type enumeration
44///
45/// Covers all common IFC entity types. Unknown types are captured with their
46/// original string representation.
47#[derive(Clone, PartialEq, Eq, Hash, Debug, Serialize, Deserialize)]
48#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
49pub enum IfcType {
50    // ========================================================================
51    // Spatial Structure
52    // ========================================================================
53    IfcProject,
54    IfcSite,
55    IfcBuilding,
56    IfcBuildingStorey,
57    IfcSpace,
58
59    // ========================================================================
60    // Building Elements
61    // ========================================================================
62    IfcWall,
63    IfcWallStandardCase,
64    IfcCurtainWall,
65    IfcSlab,
66    IfcRoof,
67    IfcBeam,
68    IfcColumn,
69    IfcDoor,
70    IfcWindow,
71    IfcStair,
72    IfcStairFlight,
73    IfcRamp,
74    IfcRampFlight,
75    IfcRailing,
76    IfcCovering,
77    IfcPlate,
78    IfcMember,
79    IfcFooting,
80    IfcPile,
81    IfcBuildingElementProxy,
82    IfcElementAssembly,
83
84    // ========================================================================
85    // Distribution Elements (MEP)
86    // ========================================================================
87    IfcDistributionElement,
88    IfcDistributionFlowElement,
89    IfcFlowTerminal,
90    IfcFlowSegment,
91    IfcFlowFitting,
92    IfcFlowController,
93    IfcFlowMovingDevice,
94    IfcFlowStorageDevice,
95    IfcFlowTreatmentDevice,
96    IfcEnergyConversionDevice,
97    IfcDistributionControlElement,
98
99    // ========================================================================
100    // Furnishing and Equipment
101    // ========================================================================
102    IfcFurnishingElement,
103    IfcFurniture,
104    IfcSystemFurnitureElement,
105
106    // ========================================================================
107    // Openings and Features
108    // ========================================================================
109    IfcOpeningElement,
110    IfcOpeningStandardCase,
111    IfcVoidingFeature,
112    IfcProjectionElement,
113
114    // ========================================================================
115    // Geometry Representations
116    // ========================================================================
117    // Swept solids
118    IfcExtrudedAreaSolid,
119    IfcExtrudedAreaSolidTapered,
120    IfcRevolvedAreaSolid,
121    IfcRevolvedAreaSolidTapered,
122    IfcSweptDiskSolid,
123    IfcSweptDiskSolidPolygonal,
124    IfcSurfaceCurveSweptAreaSolid,
125    IfcFixedReferenceSweptAreaSolid,
126
127    // Boundary representations
128    IfcFacetedBrep,
129    IfcFacetedBrepWithVoids,
130    IfcAdvancedBrep,
131    IfcAdvancedBrepWithVoids,
132
133    // Tessellated geometry (IFC4+)
134    IfcTriangulatedFaceSet,
135    IfcPolygonalFaceSet,
136    IfcTessellatedFaceSet,
137
138    // Boolean operations
139    IfcBooleanResult,
140    IfcBooleanClippingResult,
141
142    // Mapped items (instancing)
143    IfcMappedItem,
144    IfcRepresentationMap,
145
146    // CSG primitives
147    IfcBlock,
148    IfcRectangularPyramid,
149    IfcRightCircularCone,
150    IfcRightCircularCylinder,
151    IfcSphere,
152
153    // Half-space solids
154    IfcHalfSpaceSolid,
155    IfcPolygonalBoundedHalfSpace,
156    IfcBoxedHalfSpace,
157
158    // ========================================================================
159    // Profiles (2D cross-sections)
160    // ========================================================================
161    IfcArbitraryClosedProfileDef,
162    IfcArbitraryProfileDefWithVoids,
163    IfcRectangleProfileDef,
164    IfcRectangleHollowProfileDef,
165    IfcCircleProfileDef,
166    IfcCircleHollowProfileDef,
167    IfcEllipseProfileDef,
168    IfcIShapeProfileDef,
169    IfcLShapeProfileDef,
170    IfcTShapeProfileDef,
171    IfcUShapeProfileDef,
172    IfcCShapeProfileDef,
173    IfcZShapeProfileDef,
174    IfcAsymmetricIShapeProfileDef,
175    IfcTrapeziumProfileDef,
176    IfcCompositeProfileDef,
177    IfcDerivedProfileDef,
178    IfcCenterLineProfileDef,
179
180    // ========================================================================
181    // Curves
182    // ========================================================================
183    IfcPolyline,
184    IfcCompositeCurve,
185    IfcCompositeCurveSegment,
186    IfcTrimmedCurve,
187    IfcCircle,
188    IfcEllipse,
189    IfcLine,
190    IfcBSplineCurve,
191    IfcBSplineCurveWithKnots,
192    IfcRationalBSplineCurveWithKnots,
193    IfcIndexedPolyCurve,
194
195    // ========================================================================
196    // Surfaces
197    // ========================================================================
198    IfcPlane,
199    IfcCurveBoundedPlane,
200    IfcCylindricalSurface,
201    IfcBSplineSurface,
202    IfcBSplineSurfaceWithKnots,
203    IfcRationalBSplineSurfaceWithKnots,
204
205    // ========================================================================
206    // Points and Directions
207    // ========================================================================
208    IfcCartesianPoint,
209    IfcDirection,
210    IfcVector,
211    IfcCartesianPointList2D,
212    IfcCartesianPointList3D,
213
214    // ========================================================================
215    // Placement and Transforms
216    // ========================================================================
217    IfcAxis2Placement2D,
218    IfcAxis2Placement3D,
219    IfcLocalPlacement,
220    IfcCartesianTransformationOperator3D,
221    IfcCartesianTransformationOperator3DnonUniform,
222
223    // ========================================================================
224    // Representations and Contexts
225    // ========================================================================
226    IfcShapeRepresentation,
227    IfcProductDefinitionShape,
228    IfcGeometricRepresentationContext,
229    IfcGeometricRepresentationSubContext,
230
231    // ========================================================================
232    // Topology
233    // ========================================================================
234    IfcClosedShell,
235    IfcOpenShell,
236    IfcFace,
237    IfcFaceBound,
238    IfcFaceOuterBound,
239    IfcPolyLoop,
240    IfcEdgeLoop,
241    IfcOrientedEdge,
242    IfcEdgeCurve,
243    IfcVertexPoint,
244    IfcConnectedFaceSet,
245
246    // ========================================================================
247    // Relationships
248    // ========================================================================
249    IfcRelContainedInSpatialStructure,
250    IfcRelAggregates,
251    IfcRelDefinesByProperties,
252    IfcRelDefinesByType,
253    IfcRelAssociatesMaterial,
254    IfcRelVoidsElement,
255    IfcRelFillsElement,
256    IfcRelConnectsPathElements,
257    IfcRelSpaceBoundary,
258
259    // ========================================================================
260    // Properties
261    // ========================================================================
262    IfcPropertySet,
263    IfcPropertySingleValue,
264    IfcPropertyEnumeratedValue,
265    IfcPropertyBoundedValue,
266    IfcPropertyListValue,
267    IfcPropertyTableValue,
268    IfcComplexProperty,
269    IfcElementQuantity,
270    IfcQuantityLength,
271    IfcQuantityArea,
272    IfcQuantityVolume,
273    IfcQuantityCount,
274    IfcQuantityWeight,
275    IfcQuantityTime,
276
277    // ========================================================================
278    // Materials
279    // ========================================================================
280    IfcMaterial,
281    IfcMaterialLayer,
282    IfcMaterialLayerSet,
283    IfcMaterialLayerSetUsage,
284    IfcMaterialList,
285    IfcMaterialConstituentSet,
286    IfcMaterialConstituent,
287    IfcMaterialProfile,
288    IfcMaterialProfileSet,
289    IfcMaterialProfileSetUsage,
290
291    // ========================================================================
292    // Presentation (styling)
293    // ========================================================================
294    IfcStyledItem,
295    IfcSurfaceStyle,
296    IfcSurfaceStyleRendering,
297    IfcColourRgb,
298    IfcPresentationLayerAssignment,
299
300    // ========================================================================
301    // Lighting
302    // ========================================================================
303    IfcLightFixture,
304    IfcLightFixtureType,
305    IfcLightSource,
306    IfcLightSourceAmbient,
307    IfcLightSourceDirectional,
308    IfcLightSourceGoniometric,
309    IfcLightSourcePositional,
310    IfcLightSourceSpot,
311    IfcLightIntensityDistribution,
312    IfcLightDistributionData,
313
314    // ========================================================================
315    // Units
316    // ========================================================================
317    IfcUnitAssignment,
318    IfcSIUnit,
319    IfcConversionBasedUnit,
320    IfcDerivedUnit,
321    IfcMeasureWithUnit,
322
323    // ========================================================================
324    // Type definitions
325    // ========================================================================
326    IfcWallType,
327    IfcSlabType,
328    IfcBeamType,
329    IfcColumnType,
330    IfcDoorType,
331    IfcWindowType,
332    IfcCoveringType,
333    IfcRailingType,
334    IfcStairType,
335    IfcStairFlightType,
336    IfcRampType,
337    IfcRampFlightType,
338    IfcRoofType,
339    IfcMemberType,
340    IfcPlateType,
341    IfcFootingType,
342    IfcPileType,
343    IfcBuildingElementProxyType,
344
345    // ========================================================================
346    // IFC4x3 Additions (Infrastructure)
347    // ========================================================================
348    IfcAlignment,
349    IfcAlignmentCant,
350    IfcAlignmentHorizontal,
351    IfcAlignmentVertical,
352    IfcAlignmentSegment,
353    IfcRoad,
354    IfcRoadPart,
355    IfcBridge,
356    IfcBridgePart,
357    IfcRailway,
358    IfcRailwayPart,
359    IfcFacility,
360    IfcFacilityPart,
361    IfcGeotechnicalElement,
362    IfcBorehole,
363    IfcGeomodel,
364    IfcGeoslice,
365    IfcSolidStratum,
366    IfcVoidStratum,
367    IfcWaterStratum,
368    IfcEarthworksCut,
369    IfcEarthworksFill,
370    IfcEarthworksElement,
371    IfcPavement,
372    IfcCourse,
373    IfcKerb,
374    IfcDeepFoundation,
375
376    /// Unknown type - stores the original type name string
377    Unknown(String),
378}
379
380impl FromStr for IfcType {
381    type Err = std::convert::Infallible;
382
383    fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
384        Ok(Self::parse(s))
385    }
386}
387
388impl IfcType {
389    /// Parse a type name string into an IfcType
390    pub fn parse(s: &str) -> Self {
391        // Convert to uppercase for matching
392        match s.to_uppercase().as_str() {
393            // Spatial structure
394            "IFCPROJECT" => IfcType::IfcProject,
395            "IFCSITE" => IfcType::IfcSite,
396            "IFCBUILDING" => IfcType::IfcBuilding,
397            "IFCBUILDINGSTOREY" => IfcType::IfcBuildingStorey,
398            "IFCSPACE" => IfcType::IfcSpace,
399
400            // Building elements
401            "IFCWALL" => IfcType::IfcWall,
402            "IFCWALLSTANDARDCASE" => IfcType::IfcWallStandardCase,
403            "IFCCURTAINWALL" => IfcType::IfcCurtainWall,
404            "IFCSLAB" => IfcType::IfcSlab,
405            "IFCROOF" => IfcType::IfcRoof,
406            "IFCBEAM" => IfcType::IfcBeam,
407            "IFCCOLUMN" => IfcType::IfcColumn,
408            "IFCDOOR" => IfcType::IfcDoor,
409            "IFCWINDOW" => IfcType::IfcWindow,
410            "IFCSTAIR" => IfcType::IfcStair,
411            "IFCSTAIRFLIGHT" => IfcType::IfcStairFlight,
412            "IFCRAMP" => IfcType::IfcRamp,
413            "IFCRAMPFLIGHT" => IfcType::IfcRampFlight,
414            "IFCRAILING" => IfcType::IfcRailing,
415            "IFCCOVERING" => IfcType::IfcCovering,
416            "IFCPLATE" => IfcType::IfcPlate,
417            "IFCMEMBER" => IfcType::IfcMember,
418            "IFCFOOTING" => IfcType::IfcFooting,
419            "IFCPILE" => IfcType::IfcPile,
420            "IFCBUILDINGELEMENTPROXY" => IfcType::IfcBuildingElementProxy,
421            "IFCELEMENTASSEMBLY" => IfcType::IfcElementAssembly,
422
423            // Distribution elements
424            "IFCDISTRIBUTIONELEMENT" => IfcType::IfcDistributionElement,
425            "IFCDISTRIBUTIONFLOWELEMENT" => IfcType::IfcDistributionFlowElement,
426            "IFCFLOWTERMINAL" => IfcType::IfcFlowTerminal,
427            "IFCFLOWSEGMENT" => IfcType::IfcFlowSegment,
428            "IFCFLOWFITTING" => IfcType::IfcFlowFitting,
429            "IFCFLOWCONTROLLER" => IfcType::IfcFlowController,
430            "IFCFLOWMOVINGDEVICE" => IfcType::IfcFlowMovingDevice,
431            "IFCFLOWSTORAGEDEVICE" => IfcType::IfcFlowStorageDevice,
432            "IFCFLOWTREATMENTDEVICE" => IfcType::IfcFlowTreatmentDevice,
433            "IFCENERGYCONVERSIONDEVICE" => IfcType::IfcEnergyConversionDevice,
434            "IFCDISTRIBUTIONCONTROLELEMENT" => IfcType::IfcDistributionControlElement,
435
436            // Furnishing
437            "IFCFURNISHINGELEMENT" => IfcType::IfcFurnishingElement,
438            "IFCFURNITURE" => IfcType::IfcFurniture,
439            "IFCSYSTEMFURNITUREELEMENT" => IfcType::IfcSystemFurnitureElement,
440
441            // Openings
442            "IFCOPENINGELEMENT" => IfcType::IfcOpeningElement,
443            "IFCOPENINGSTANDARDCASE" => IfcType::IfcOpeningStandardCase,
444            "IFCVOIDINGFEATURE" => IfcType::IfcVoidingFeature,
445            "IFCPROJECTIONELEMENT" => IfcType::IfcProjectionElement,
446
447            // Geometry - Swept solids
448            "IFCEXTRUDEDAREASOLID" => IfcType::IfcExtrudedAreaSolid,
449            "IFCEXTRUDEDAREASOLIDTAPERED" => IfcType::IfcExtrudedAreaSolidTapered,
450            "IFCREVOLVEDAREASOLID" => IfcType::IfcRevolvedAreaSolid,
451            "IFCREVOLVEDAREASOLIDTAPERED" => IfcType::IfcRevolvedAreaSolidTapered,
452            "IFCSWEPTDISKSOLID" => IfcType::IfcSweptDiskSolid,
453            "IFCSWEPTDISKSOLIDPOLYGONAL" => IfcType::IfcSweptDiskSolidPolygonal,
454            "IFCSURFACECURVESWEPTAREASOLID" => IfcType::IfcSurfaceCurveSweptAreaSolid,
455            "IFCFIXEDREFERENCESWEPTAREASOLID" => IfcType::IfcFixedReferenceSweptAreaSolid,
456
457            // Geometry - BREPs
458            "IFCFACETEDBREP" => IfcType::IfcFacetedBrep,
459            "IFCFACETEDBREPWITHVOIDS" => IfcType::IfcFacetedBrepWithVoids,
460            "IFCADVANCEDBREP" => IfcType::IfcAdvancedBrep,
461            "IFCADVANCEDBREPWITHVOIDS" => IfcType::IfcAdvancedBrepWithVoids,
462
463            // Geometry - Tessellated
464            "IFCTRIANGULATEDFACESET" => IfcType::IfcTriangulatedFaceSet,
465            "IFCPOLYGONALFACESET" => IfcType::IfcPolygonalFaceSet,
466            "IFCTESSELLATEDFACESET" => IfcType::IfcTessellatedFaceSet,
467
468            // Geometry - Boolean
469            "IFCBOOLEANRESULT" => IfcType::IfcBooleanResult,
470            "IFCBOOLEANCLIPPINGRESULT" => IfcType::IfcBooleanClippingResult,
471
472            // Geometry - Mapped items
473            "IFCMAPPEDITEM" => IfcType::IfcMappedItem,
474            "IFCREPRESENTATIONMAP" => IfcType::IfcRepresentationMap,
475
476            // Geometry - CSG primitives
477            "IFCBLOCK" => IfcType::IfcBlock,
478            "IFCRECTANGULARPYRAMID" => IfcType::IfcRectangularPyramid,
479            "IFCRIGHTCIRCULARCONE" => IfcType::IfcRightCircularCone,
480            "IFCRIGHTCIRCULARCYLINDER" => IfcType::IfcRightCircularCylinder,
481            "IFCSPHERE" => IfcType::IfcSphere,
482
483            // Geometry - Half-space
484            "IFCHALFSPACESOLID" => IfcType::IfcHalfSpaceSolid,
485            "IFCPOLYGONALBOUNDEDHALFSPACE" => IfcType::IfcPolygonalBoundedHalfSpace,
486            "IFCBOXEDHALFSPACE" => IfcType::IfcBoxedHalfSpace,
487
488            // Profiles
489            "IFCARBITRARYCLOSEDPROFILEDEF" => IfcType::IfcArbitraryClosedProfileDef,
490            "IFCARBITRARYPROFILEDEFWITHVOIDS" => IfcType::IfcArbitraryProfileDefWithVoids,
491            "IFCRECTANGLEPROFILEDEF" => IfcType::IfcRectangleProfileDef,
492            "IFCRECTANGLEHOLLOWPROFILEDEF" => IfcType::IfcRectangleHollowProfileDef,
493            "IFCCIRCLEPROFILEDEF" => IfcType::IfcCircleProfileDef,
494            "IFCCIRCLEHOLLOWPROFILEDEF" => IfcType::IfcCircleHollowProfileDef,
495            "IFCELLIPSEPROFILEDEF" => IfcType::IfcEllipseProfileDef,
496            "IFCISHAPEPROFILEDEF" => IfcType::IfcIShapeProfileDef,
497            "IFCLSHAPEPROFILEDEF" => IfcType::IfcLShapeProfileDef,
498            "IFCTSHAPEPROFILEDEF" => IfcType::IfcTShapeProfileDef,
499            "IFCUSHAPEPROFILEDEF" => IfcType::IfcUShapeProfileDef,
500            "IFCCSHAPEPROFILEDEF" => IfcType::IfcCShapeProfileDef,
501            "IFCZSHAPEPROFILEDEF" => IfcType::IfcZShapeProfileDef,
502            "IFCASYMMETRICISHAPEPROFILEDEF" => IfcType::IfcAsymmetricIShapeProfileDef,
503            "IFCTRAPEZIUMPROFILEDEF" => IfcType::IfcTrapeziumProfileDef,
504            "IFCCOMPOSITEPROFILEDEF" => IfcType::IfcCompositeProfileDef,
505            "IFCDERIVEDPROFILEDEF" => IfcType::IfcDerivedProfileDef,
506            "IFCCENTERLINEPROFILEDEF" => IfcType::IfcCenterLineProfileDef,
507
508            // Curves
509            "IFCPOLYLINE" => IfcType::IfcPolyline,
510            "IFCCOMPOSITECURVE" => IfcType::IfcCompositeCurve,
511            "IFCCOMPOSITECURVESEGMENT" => IfcType::IfcCompositeCurveSegment,
512            "IFCTRIMMEDCURVE" => IfcType::IfcTrimmedCurve,
513            "IFCCIRCLE" => IfcType::IfcCircle,
514            "IFCELLIPSE" => IfcType::IfcEllipse,
515            "IFCLINE" => IfcType::IfcLine,
516            "IFCBSPLINECURVE" => IfcType::IfcBSplineCurve,
517            "IFCBSPLINECURVEWITHKNOTS" => IfcType::IfcBSplineCurveWithKnots,
518            "IFCRATIONALBSPLINECURVEWITHKNOTS" => IfcType::IfcRationalBSplineCurveWithKnots,
519            "IFCINDEXEDPOLYCURVE" => IfcType::IfcIndexedPolyCurve,
520
521            // Surfaces
522            "IFCPLANE" => IfcType::IfcPlane,
523            "IFCCURVEBOUNDEDPLANE" => IfcType::IfcCurveBoundedPlane,
524            "IFCCYLINDRICALSURFACE" => IfcType::IfcCylindricalSurface,
525            "IFCBSPLINESURFACE" => IfcType::IfcBSplineSurface,
526            "IFCBSPLINESURFACEWITHKNOTS" => IfcType::IfcBSplineSurfaceWithKnots,
527            "IFCRATIONALBSPLINESURFACEWITHKNOTS" => IfcType::IfcRationalBSplineSurfaceWithKnots,
528
529            // Points and directions
530            "IFCCARTESIANPOINT" => IfcType::IfcCartesianPoint,
531            "IFCDIRECTION" => IfcType::IfcDirection,
532            "IFCVECTOR" => IfcType::IfcVector,
533            "IFCCARTESIANPOINTLIST2D" => IfcType::IfcCartesianPointList2D,
534            "IFCCARTESIANPOINTLIST3D" => IfcType::IfcCartesianPointList3D,
535
536            // Placement
537            "IFCAXIS2PLACEMENT2D" => IfcType::IfcAxis2Placement2D,
538            "IFCAXIS2PLACEMENT3D" => IfcType::IfcAxis2Placement3D,
539            "IFCLOCALPLACEMENT" => IfcType::IfcLocalPlacement,
540            "IFCCARTESIANTRANSFORMATIONOPERATOR3D" => IfcType::IfcCartesianTransformationOperator3D,
541            "IFCCARTESIANTRANSFORMATIONOPERATOR3DNONUNIFORM" => {
542                IfcType::IfcCartesianTransformationOperator3DnonUniform
543            }
544
545            // Representations
546            "IFCSHAPEREPRESENTATION" => IfcType::IfcShapeRepresentation,
547            "IFCPRODUCTDEFINITIONSHAPE" => IfcType::IfcProductDefinitionShape,
548            "IFCGEOMETRICREPRESENTATIONCONTEXT" => IfcType::IfcGeometricRepresentationContext,
549            "IFCGEOMETRICREPRESENTATIONSUBCONTEXT" => IfcType::IfcGeometricRepresentationSubContext,
550
551            // Topology
552            "IFCCLOSEDSHELL" => IfcType::IfcClosedShell,
553            "IFCOPENSHELL" => IfcType::IfcOpenShell,
554            "IFCFACE" => IfcType::IfcFace,
555            "IFCFACEBOUND" => IfcType::IfcFaceBound,
556            "IFCFACEOUTERBOUND" => IfcType::IfcFaceOuterBound,
557            "IFCPOLYLOOP" => IfcType::IfcPolyLoop,
558            "IFCEDGELOOP" => IfcType::IfcEdgeLoop,
559            "IFCORIENTEDEDGE" => IfcType::IfcOrientedEdge,
560            "IFCEDGECURVE" => IfcType::IfcEdgeCurve,
561            "IFCVERTEXPOINT" => IfcType::IfcVertexPoint,
562            "IFCCONNECTEDFACESET" => IfcType::IfcConnectedFaceSet,
563
564            // Relationships
565            "IFCRELCONTAINEDINSPATIALSTRUCTURE" => IfcType::IfcRelContainedInSpatialStructure,
566            "IFCRELAGGREGATES" => IfcType::IfcRelAggregates,
567            "IFCRELDEFINESBYPROPERTIES" => IfcType::IfcRelDefinesByProperties,
568            "IFCRELDEFINESBYTYPE" => IfcType::IfcRelDefinesByType,
569            "IFCRELASSOCIATESMATERIAL" => IfcType::IfcRelAssociatesMaterial,
570            "IFCRELVOIDSELEMENT" => IfcType::IfcRelVoidsElement,
571            "IFCRELFILLSELEMENT" => IfcType::IfcRelFillsElement,
572            "IFCRELCONNECTSPATHELEMENTS" => IfcType::IfcRelConnectsPathElements,
573            "IFCRELSPACEBOUNDARY" => IfcType::IfcRelSpaceBoundary,
574
575            // Properties
576            "IFCPROPERTYSET" => IfcType::IfcPropertySet,
577            "IFCPROPERTYSINGLEVALUE" => IfcType::IfcPropertySingleValue,
578            "IFCPROPERTYENUMERATEDVALUE" => IfcType::IfcPropertyEnumeratedValue,
579            "IFCPROPERTYBOUNDEDVALUE" => IfcType::IfcPropertyBoundedValue,
580            "IFCPROPERTYLISTVALUE" => IfcType::IfcPropertyListValue,
581            "IFCPROPERTYTABLEVALUE" => IfcType::IfcPropertyTableValue,
582            "IFCCOMPLEXPROPERTY" => IfcType::IfcComplexProperty,
583            "IFCELEMENTQUANTITY" => IfcType::IfcElementQuantity,
584            "IFCQUANTITYLENGTH" => IfcType::IfcQuantityLength,
585            "IFCQUANTITYAREA" => IfcType::IfcQuantityArea,
586            "IFCQUANTITYVOLUME" => IfcType::IfcQuantityVolume,
587            "IFCQUANTITYCOUNT" => IfcType::IfcQuantityCount,
588            "IFCQUANTITYWEIGHT" => IfcType::IfcQuantityWeight,
589            "IFCQUANTITYTIME" => IfcType::IfcQuantityTime,
590
591            // Materials
592            "IFCMATERIAL" => IfcType::IfcMaterial,
593            "IFCMATERIALLAYER" => IfcType::IfcMaterialLayer,
594            "IFCMATERIALLAYERSET" => IfcType::IfcMaterialLayerSet,
595            "IFCMATERIALLAYERSETUSAGE" => IfcType::IfcMaterialLayerSetUsage,
596            "IFCMATERIALLIST" => IfcType::IfcMaterialList,
597            "IFCMATERIALCONSTITUENTSET" => IfcType::IfcMaterialConstituentSet,
598            "IFCMATERIALCONSTITUENT" => IfcType::IfcMaterialConstituent,
599            "IFCMATERIALPROFILE" => IfcType::IfcMaterialProfile,
600            "IFCMATERIALPROFILESET" => IfcType::IfcMaterialProfileSet,
601            "IFCMATERIALPROFILESETUSAGE" => IfcType::IfcMaterialProfileSetUsage,
602
603            // Presentation
604            "IFCSTYLEDITEM" => IfcType::IfcStyledItem,
605            "IFCSURFACESTYLE" => IfcType::IfcSurfaceStyle,
606            "IFCSURFACESTYLERENDERING" => IfcType::IfcSurfaceStyleRendering,
607            "IFCCOLOURRGB" => IfcType::IfcColourRgb,
608            "IFCPRESENTATIONLAYERASSIGNMENT" => IfcType::IfcPresentationLayerAssignment,
609
610            // Lighting
611            "IFCLIGHTFIXTURE" => IfcType::IfcLightFixture,
612            "IFCLIGHTFIXTURETYPE" => IfcType::IfcLightFixtureType,
613            "IFCLIGHTSOURCE" => IfcType::IfcLightSource,
614            "IFCLIGHTSOURCEAMBIENT" => IfcType::IfcLightSourceAmbient,
615            "IFCLIGHTSOURCEDIRECTIONAL" => IfcType::IfcLightSourceDirectional,
616            "IFCLIGHTSOURCEGONIOMETRIC" => IfcType::IfcLightSourceGoniometric,
617            "IFCLIGHTSOURCEPOSITIONAL" => IfcType::IfcLightSourcePositional,
618            "IFCLIGHTSOURCESPOT" => IfcType::IfcLightSourceSpot,
619            "IFCLIGHTINTENSITYDISTRIBUTION" => IfcType::IfcLightIntensityDistribution,
620            "IFCLIGHTDISTRIBUTIONDATA" => IfcType::IfcLightDistributionData,
621
622            // Units
623            "IFCUNITASSIGNMENT" => IfcType::IfcUnitAssignment,
624            "IFCSIUNIT" => IfcType::IfcSIUnit,
625            "IFCCONVERSIONBASEDUNIT" => IfcType::IfcConversionBasedUnit,
626            "IFCDERIVEDUNIT" => IfcType::IfcDerivedUnit,
627            "IFCMEASUREWITHUNIT" => IfcType::IfcMeasureWithUnit,
628
629            // Type definitions
630            "IFCWALLTYPE" => IfcType::IfcWallType,
631            "IFCSLABTYPE" => IfcType::IfcSlabType,
632            "IFCBEAMTYPE" => IfcType::IfcBeamType,
633            "IFCCOLUMNTYPE" => IfcType::IfcColumnType,
634            "IFCDOORTYPE" => IfcType::IfcDoorType,
635            "IFCWINDOWTYPE" => IfcType::IfcWindowType,
636            "IFCCOVERINGTYPE" => IfcType::IfcCoveringType,
637            "IFCRAILINGTYPE" => IfcType::IfcRailingType,
638            "IFCSTAIRTYPE" => IfcType::IfcStairType,
639            "IFCSTAIRFLIGHTTYPE" => IfcType::IfcStairFlightType,
640            "IFCRAMPTYPE" => IfcType::IfcRampType,
641            "IFCRAMPFLIGHTTYPE" => IfcType::IfcRampFlightType,
642            "IFCROOFTYPE" => IfcType::IfcRoofType,
643            "IFCMEMBERTYPE" => IfcType::IfcMemberType,
644            "IFCPLATETYPE" => IfcType::IfcPlateType,
645            "IFCFOOTINGTYPE" => IfcType::IfcFootingType,
646            "IFCPILETYPE" => IfcType::IfcPileType,
647            "IFCBUILDINGELEMENTPROXYTYPE" => IfcType::IfcBuildingElementProxyType,
648
649            // IFC4x3 Infrastructure
650            "IFCALIGNMENT" => IfcType::IfcAlignment,
651            "IFCALIGNMENTCANT" => IfcType::IfcAlignmentCant,
652            "IFCALIGNMENTHORIZONTAL" => IfcType::IfcAlignmentHorizontal,
653            "IFCALIGNMENTVERTICAL" => IfcType::IfcAlignmentVertical,
654            "IFCALIGNMENTSEGMENT" => IfcType::IfcAlignmentSegment,
655            "IFCROAD" => IfcType::IfcRoad,
656            "IFCROADPART" => IfcType::IfcRoadPart,
657            "IFCBRIDGE" => IfcType::IfcBridge,
658            "IFCBRIDGEPART" => IfcType::IfcBridgePart,
659            "IFCRAILWAY" => IfcType::IfcRailway,
660            "IFCRAILWAYPART" => IfcType::IfcRailwayPart,
661            "IFCFACILITY" => IfcType::IfcFacility,
662            "IFCFACILITYPART" => IfcType::IfcFacilityPart,
663            "IFCGEOTECHNICALELEMENT" => IfcType::IfcGeotechnicalElement,
664            "IFCBOREHOLE" => IfcType::IfcBorehole,
665            "IFCGEOMODEL" => IfcType::IfcGeomodel,
666            "IFCGEOSLICE" => IfcType::IfcGeoslice,
667            "IFCSOLIDSTRATUM" => IfcType::IfcSolidStratum,
668            "IFCVOIDSTRATUM" => IfcType::IfcVoidStratum,
669            "IFCWATERSTRATUM" => IfcType::IfcWaterStratum,
670            "IFCEARTHWORKSCUT" => IfcType::IfcEarthworksCut,
671            "IFCEARTHWORKSFILL" => IfcType::IfcEarthworksFill,
672            "IFCEARTHWORKSELEMENT" => IfcType::IfcEarthworksElement,
673            "IFCPAVEMENT" => IfcType::IfcPavement,
674            "IFCCOURSE" => IfcType::IfcCourse,
675            "IFCKERB" => IfcType::IfcKerb,
676            "IFCDEEPFOUNDATION" => IfcType::IfcDeepFoundation,
677
678            // Unknown
679            _ => IfcType::Unknown(s.to_string()),
680        }
681    }
682
683    /// Get the type name as a string
684    pub fn name(&self) -> &str {
685        match self {
686            IfcType::Unknown(s) => s,
687            _ => {
688                // For known types, return the variant name
689                // This uses the debug representation which includes the type name
690                // A more elegant solution would use a macro, but this works
691                match self {
692                    IfcType::IfcProject => "IFCPROJECT",
693                    IfcType::IfcSite => "IFCSITE",
694                    IfcType::IfcBuilding => "IFCBUILDING",
695                    IfcType::IfcBuildingStorey => "IFCBUILDINGSTOREY",
696                    IfcType::IfcSpace => "IFCSPACE",
697                    IfcType::IfcWall => "IFCWALL",
698                    IfcType::IfcWallStandardCase => "IFCWALLSTANDARDCASE",
699                    IfcType::IfcCurtainWall => "IFCCURTAINWALL",
700                    IfcType::IfcSlab => "IFCSLAB",
701                    IfcType::IfcRoof => "IFCROOF",
702                    IfcType::IfcBeam => "IFCBEAM",
703                    IfcType::IfcColumn => "IFCCOLUMN",
704                    IfcType::IfcDoor => "IFCDOOR",
705                    IfcType::IfcWindow => "IFCWINDOW",
706                    IfcType::IfcStair => "IFCSTAIR",
707                    IfcType::IfcStairFlight => "IFCSTAIRFLIGHT",
708                    IfcType::IfcRamp => "IFCRAMP",
709                    IfcType::IfcRampFlight => "IFCRAMPFLIGHT",
710                    IfcType::IfcRailing => "IFCRAILING",
711                    IfcType::IfcCovering => "IFCCOVERING",
712                    IfcType::IfcPlate => "IFCPLATE",
713                    IfcType::IfcMember => "IFCMEMBER",
714                    IfcType::IfcFooting => "IFCFOOTING",
715                    IfcType::IfcPile => "IFCPILE",
716                    IfcType::IfcBuildingElementProxy => "IFCBUILDINGELEMENTPROXY",
717                    IfcType::IfcElementAssembly => "IFCELEMENTASSEMBLY",
718                    IfcType::IfcExtrudedAreaSolid => "IFCEXTRUDEDAREASOLID",
719                    IfcType::IfcFacetedBrep => "IFCFACETEDBREP",
720                    IfcType::IfcTriangulatedFaceSet => "IFCTRIANGULATEDFACESET",
721                    IfcType::IfcMappedItem => "IFCMAPPEDITEM",
722                    IfcType::IfcBooleanClippingResult => "IFCBOOLEANCLIPPINGRESULT",
723                    // Add more as needed, or use a macro for all variants
724                    _ => "UNKNOWN",
725                }
726            }
727        }
728    }
729
730    /// Check if this type represents a building element with potential geometry
731    pub fn has_geometry(&self) -> bool {
732        matches!(
733            self,
734            IfcType::IfcWall
735                | IfcType::IfcWallStandardCase
736                | IfcType::IfcCurtainWall
737                | IfcType::IfcSlab
738                | IfcType::IfcRoof
739                | IfcType::IfcBeam
740                | IfcType::IfcColumn
741                | IfcType::IfcDoor
742                | IfcType::IfcWindow
743                | IfcType::IfcStair
744                | IfcType::IfcStairFlight
745                | IfcType::IfcRamp
746                | IfcType::IfcRampFlight
747                | IfcType::IfcRailing
748                | IfcType::IfcCovering
749                | IfcType::IfcPlate
750                | IfcType::IfcMember
751                | IfcType::IfcFooting
752                | IfcType::IfcPile
753                | IfcType::IfcLightFixture
754                | IfcType::IfcBuildingElementProxy
755                | IfcType::IfcFurnishingElement
756                | IfcType::IfcFurniture
757                | IfcType::IfcDistributionElement
758                | IfcType::IfcFlowTerminal
759                | IfcType::IfcFlowSegment
760                | IfcType::IfcFlowFitting
761                | IfcType::IfcOpeningElement
762        )
763    }
764
765    /// Check if this type is a spatial structure element
766    pub fn is_spatial(&self) -> bool {
767        matches!(
768            self,
769            IfcType::IfcProject
770                | IfcType::IfcSite
771                | IfcType::IfcBuilding
772                | IfcType::IfcBuildingStorey
773                | IfcType::IfcSpace
774                | IfcType::IfcFacility
775                | IfcType::IfcFacilityPart
776        )
777    }
778}
779
780impl Default for IfcType {
781    fn default() -> Self {
782        IfcType::Unknown(String::new())
783    }
784}
785
786impl fmt::Display for IfcType {
787    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
788        write!(f, "{}", self.name())
789    }
790}
791
792/// Decoded attribute value
793///
794/// Represents any value that can appear in an IFC entity's attribute list.
795#[derive(Clone, Debug, PartialEq, Default)]
796pub enum AttributeValue {
797    /// Null value ($)
798    #[default]
799    Null,
800    /// Derived value (*)
801    Derived,
802    /// Entity reference (#123)
803    EntityRef(EntityId),
804    /// Boolean value
805    Bool(bool),
806    /// Integer value
807    Integer(i64),
808    /// Floating point value
809    Float(f64),
810    /// String value
811    String(String),
812    /// Enumeration value (.VALUE.)
813    Enum(String),
814    /// List of values
815    List(Vec<AttributeValue>),
816    /// Typed value like IFCLABEL('text')
817    TypedValue(String, Vec<AttributeValue>),
818}
819
820impl AttributeValue {
821    /// Try to get as entity reference
822    pub fn as_entity_ref(&self) -> Option<EntityId> {
823        match self {
824            AttributeValue::EntityRef(id) => Some(*id),
825            _ => None,
826        }
827    }
828
829    /// Try to get as string
830    pub fn as_string(&self) -> Option<&str> {
831        match self {
832            AttributeValue::String(s) => Some(s),
833            AttributeValue::TypedValue(_, args) if !args.is_empty() => args[0].as_string(),
834            _ => None,
835        }
836    }
837
838    /// Try to get as float
839    pub fn as_float(&self) -> Option<f64> {
840        match self {
841            AttributeValue::Float(f) => Some(*f),
842            AttributeValue::Integer(i) => Some(*i as f64),
843            AttributeValue::TypedValue(_, args) if !args.is_empty() => args[0].as_float(),
844            _ => None,
845        }
846    }
847
848    /// Try to get as integer
849    pub fn as_integer(&self) -> Option<i64> {
850        match self {
851            AttributeValue::Integer(i) => Some(*i),
852            _ => None,
853        }
854    }
855
856    /// Try to get as boolean
857    pub fn as_bool(&self) -> Option<bool> {
858        match self {
859            AttributeValue::Bool(b) => Some(*b),
860            AttributeValue::Enum(s) => match s.to_uppercase().as_str() {
861                "TRUE" | "T" => Some(true),
862                "FALSE" | "F" => Some(false),
863                _ => None,
864            },
865            _ => None,
866        }
867    }
868
869    /// Try to get as enum string
870    pub fn as_enum(&self) -> Option<&str> {
871        match self {
872            AttributeValue::Enum(s) => Some(s),
873            _ => None,
874        }
875    }
876
877    /// Try to get as list
878    pub fn as_list(&self) -> Option<&[AttributeValue]> {
879        match self {
880            AttributeValue::List(list) => Some(list),
881            _ => None,
882        }
883    }
884
885    /// Check if this is a null value
886    pub fn is_null(&self) -> bool {
887        matches!(self, AttributeValue::Null)
888    }
889
890    /// Check if this is a derived value
891    pub fn is_derived(&self) -> bool {
892        matches!(self, AttributeValue::Derived)
893    }
894}
895
896/// Decoded IFC entity
897///
898/// Represents a fully decoded IFC entity with its ID, type, and attribute values.
899#[derive(Clone, Debug)]
900pub struct DecodedEntity {
901    /// Entity ID
902    pub id: EntityId,
903    /// Entity type
904    pub ifc_type: IfcType,
905    /// Attribute values in order
906    pub attributes: Vec<AttributeValue>,
907}
908
909impl DecodedEntity {
910    /// Get attribute at index
911    pub fn get(&self, index: usize) -> Option<&AttributeValue> {
912        self.attributes.get(index)
913    }
914
915    /// Get entity reference at index
916    pub fn get_ref(&self, index: usize) -> Option<EntityId> {
917        self.get(index).and_then(|v| v.as_entity_ref())
918    }
919
920    /// Get string at index
921    pub fn get_string(&self, index: usize) -> Option<&str> {
922        self.get(index).and_then(|v| v.as_string())
923    }
924
925    /// Get float at index
926    pub fn get_float(&self, index: usize) -> Option<f64> {
927        self.get(index).and_then(|v| v.as_float())
928    }
929
930    /// Get integer at index
931    pub fn get_integer(&self, index: usize) -> Option<i64> {
932        self.get(index).and_then(|v| v.as_integer())
933    }
934
935    /// Get list at index
936    pub fn get_list(&self, index: usize) -> Option<&[AttributeValue]> {
937        self.get(index).and_then(|v| v.as_list())
938    }
939
940    /// Get boolean at index
941    pub fn get_bool(&self, index: usize) -> Option<bool> {
942        self.get(index).and_then(|v| v.as_bool())
943    }
944
945    /// Get enum string at index
946    pub fn get_enum(&self, index: usize) -> Option<&str> {
947        self.get(index).and_then(|v| v.as_enum())
948    }
949
950    /// Get list of entity references at index
951    pub fn get_refs(&self, index: usize) -> Option<Vec<EntityId>> {
952        self.get_list(index)
953            .map(|list| list.iter().filter_map(|v| v.as_entity_ref()).collect())
954    }
955}
956
957/// GPU-ready mesh data
958///
959/// Contains flattened vertex data suitable for GPU rendering.
960#[derive(Clone, Debug, Default)]
961pub struct MeshData {
962    /// Vertex positions as flattened [x, y, z, x, y, z, ...]
963    pub positions: Vec<f32>,
964    /// Vertex normals as flattened [nx, ny, nz, nx, ny, nz, ...]
965    pub normals: Vec<f32>,
966    /// Triangle indices
967    pub indices: Vec<u32>,
968}
969
970impl MeshData {
971    /// Create a new empty mesh
972    pub fn new() -> Self {
973        Self::default()
974    }
975
976    /// Create mesh with pre-allocated capacity
977    pub fn with_capacity(vertex_count: usize, index_count: usize) -> Self {
978        Self {
979            positions: Vec::with_capacity(vertex_count * 3),
980            normals: Vec::with_capacity(vertex_count * 3),
981            indices: Vec::with_capacity(index_count),
982        }
983    }
984
985    /// Check if mesh is empty
986    pub fn is_empty(&self) -> bool {
987        self.positions.is_empty()
988    }
989
990    /// Get vertex count
991    pub fn vertex_count(&self) -> usize {
992        self.positions.len() / 3
993    }
994
995    /// Get triangle count
996    pub fn triangle_count(&self) -> usize {
997        self.indices.len() / 3
998    }
999
1000    /// Merge another mesh into this one
1001    pub fn merge(&mut self, other: &MeshData) {
1002        let vertex_offset = self.vertex_count() as u32;
1003
1004        self.positions.extend_from_slice(&other.positions);
1005        self.normals.extend_from_slice(&other.normals);
1006        self.indices
1007            .extend(other.indices.iter().map(|i| i + vertex_offset));
1008    }
1009}
1010
1011/// Model metadata extracted from IFC header
1012#[derive(Clone, Debug, Default)]
1013pub struct ModelMetadata {
1014    /// IFC schema version (e.g., "IFC2X3", "IFC4", "IFC4X3")
1015    pub schema_version: String,
1016    /// Originating system (CAD application)
1017    pub originating_system: Option<String>,
1018    /// Preprocessor version
1019    pub preprocessor_version: Option<String>,
1020    /// File name from header
1021    pub file_name: Option<String>,
1022    /// File description
1023    pub file_description: Option<String>,
1024    /// Author
1025    pub author: Option<String>,
1026    /// Organization
1027    pub organization: Option<String>,
1028    /// Timestamp
1029    pub timestamp: Option<String>,
1030}