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