use serde::{Deserialize, Serialize};
use std::fmt;
use std::str::FromStr;
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Serialize, Deserialize, Default)]
pub struct EntityId(pub u32);
impl fmt::Display for EntityId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "#{}", self.0)
}
}
impl From<u32> for EntityId {
fn from(id: u32) -> Self {
EntityId(id)
}
}
impl From<EntityId> for u32 {
fn from(id: EntityId) -> Self {
id.0
}
}
impl From<EntityId> for u64 {
fn from(id: EntityId) -> Self {
id.0 as u64
}
}
#[derive(Clone, PartialEq, Eq, Hash, Debug, Serialize, Deserialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum IfcType {
IfcRoot,
IfcObjectDefinition,
IfcObject,
IfcProduct,
IfcElement,
IfcBuiltElement,
IfcSpatialElement,
IfcSpatialStructureElement,
IfcExternalSpatialStructureElement,
IfcExternalSpatialElement,
IfcSpatialZone,
IfcCivilElement,
IfcGeographicElement,
IfcAnnotation,
IfcPort,
IfcFeatureElement,
IfcFeatureElementAddition,
IfcFeatureElementSubtraction,
IfcGeotechnicalAssembly,
IfcProject,
IfcSite,
IfcBuilding,
IfcBuildingStorey,
IfcSpace,
IfcWall,
IfcWallStandardCase,
IfcCurtainWall,
IfcSlab,
IfcRoof,
IfcBeam,
IfcColumn,
IfcDoor,
IfcWindow,
IfcStair,
IfcStairFlight,
IfcRamp,
IfcRampFlight,
IfcRailing,
IfcCovering,
IfcPlate,
IfcMember,
IfcFooting,
IfcPile,
IfcBuildingElementProxy,
IfcElementAssembly,
IfcDistributionElement,
IfcDistributionFlowElement,
IfcFlowTerminal,
IfcFlowSegment,
IfcFlowFitting,
IfcFlowController,
IfcFlowMovingDevice,
IfcFlowStorageDevice,
IfcFlowTreatmentDevice,
IfcEnergyConversionDevice,
IfcDistributionControlElement,
IfcCableSegment,
IfcCableCarrierSegment,
IfcCableCarrierFitting,
IfcPipeSegment,
IfcPipeFitting,
IfcSpaceHeater,
IfcAirTerminal,
IfcFurnishingElement,
IfcFurniture,
IfcSystemFurnitureElement,
IfcOpeningElement,
IfcOpeningStandardCase,
IfcVoidingFeature,
IfcProjectionElement,
IfcExtrudedAreaSolid,
IfcExtrudedAreaSolidTapered,
IfcRevolvedAreaSolid,
IfcRevolvedAreaSolidTapered,
IfcSweptDiskSolid,
IfcSweptDiskSolidPolygonal,
IfcSurfaceCurveSweptAreaSolid,
IfcFixedReferenceSweptAreaSolid,
IfcFacetedBrep,
IfcFacetedBrepWithVoids,
IfcAdvancedBrep,
IfcAdvancedBrepWithVoids,
IfcTriangulatedFaceSet,
IfcPolygonalFaceSet,
IfcTessellatedFaceSet,
IfcBooleanResult,
IfcBooleanClippingResult,
IfcMappedItem,
IfcRepresentationMap,
IfcBlock,
IfcRectangularPyramid,
IfcRightCircularCone,
IfcRightCircularCylinder,
IfcSphere,
IfcHalfSpaceSolid,
IfcPolygonalBoundedHalfSpace,
IfcBoxedHalfSpace,
IfcArbitraryClosedProfileDef,
IfcArbitraryProfileDefWithVoids,
IfcRectangleProfileDef,
IfcRectangleHollowProfileDef,
IfcCircleProfileDef,
IfcCircleHollowProfileDef,
IfcEllipseProfileDef,
IfcIShapeProfileDef,
IfcLShapeProfileDef,
IfcTShapeProfileDef,
IfcUShapeProfileDef,
IfcCShapeProfileDef,
IfcZShapeProfileDef,
IfcAsymmetricIShapeProfileDef,
IfcTrapeziumProfileDef,
IfcCompositeProfileDef,
IfcDerivedProfileDef,
IfcCenterLineProfileDef,
IfcPolyline,
IfcCompositeCurve,
IfcCompositeCurveSegment,
IfcTrimmedCurve,
IfcCircle,
IfcEllipse,
IfcLine,
IfcBSplineCurve,
IfcBSplineCurveWithKnots,
IfcRationalBSplineCurveWithKnots,
IfcIndexedPolyCurve,
IfcPlane,
IfcCurveBoundedPlane,
IfcCylindricalSurface,
IfcBSplineSurface,
IfcBSplineSurfaceWithKnots,
IfcRationalBSplineSurfaceWithKnots,
IfcCartesianPoint,
IfcDirection,
IfcVector,
IfcCartesianPointList2D,
IfcCartesianPointList3D,
IfcAxis2Placement2D,
IfcAxis2Placement3D,
IfcLocalPlacement,
IfcCartesianTransformationOperator3D,
IfcCartesianTransformationOperator3DnonUniform,
IfcShapeRepresentation,
IfcProductDefinitionShape,
IfcGeometricRepresentationContext,
IfcGeometricRepresentationSubContext,
IfcClosedShell,
IfcOpenShell,
IfcFace,
IfcFaceBound,
IfcFaceOuterBound,
IfcPolyLoop,
IfcEdgeLoop,
IfcOrientedEdge,
IfcEdgeCurve,
IfcVertexPoint,
IfcConnectedFaceSet,
IfcRelContainedInSpatialStructure,
IfcRelAggregates,
IfcRelDefinesByProperties,
IfcRelDefinesByType,
IfcRelAssociatesMaterial,
IfcRelVoidsElement,
IfcRelFillsElement,
IfcRelConnectsPathElements,
IfcRelSpaceBoundary,
IfcRelAssignsToGroup,
IfcPropertySet,
IfcPropertySingleValue,
IfcPropertyEnumeratedValue,
IfcPropertyBoundedValue,
IfcPropertyListValue,
IfcPropertyTableValue,
IfcComplexProperty,
IfcElementQuantity,
IfcQuantityLength,
IfcQuantityArea,
IfcQuantityVolume,
IfcQuantityCount,
IfcQuantityWeight,
IfcQuantityTime,
IfcMaterial,
IfcMaterialLayer,
IfcMaterialLayerSet,
IfcMaterialLayerSetUsage,
IfcMaterialList,
IfcMaterialConstituentSet,
IfcMaterialConstituent,
IfcMaterialProfile,
IfcMaterialProfileSet,
IfcMaterialProfileSetUsage,
IfcStyledItem,
IfcSurfaceStyle,
IfcSurfaceStyleRendering,
IfcColourRgb,
IfcPresentationLayerAssignment,
IfcLightFixture,
IfcLightFixtureType,
IfcLightSource,
IfcLightSourceAmbient,
IfcLightSourceDirectional,
IfcLightSourceGoniometric,
IfcLightSourcePositional,
IfcLightSourceSpot,
IfcLightIntensityDistribution,
IfcLightDistributionData,
IfcUnitAssignment,
IfcSIUnit,
IfcConversionBasedUnit,
IfcDerivedUnit,
IfcMeasureWithUnit,
IfcWallType,
IfcSlabType,
IfcBeamType,
IfcColumnType,
IfcDoorType,
IfcWindowType,
IfcCoveringType,
IfcRailingType,
IfcStairType,
IfcStairFlightType,
IfcRampType,
IfcRampFlightType,
IfcRoofType,
IfcMemberType,
IfcPlateType,
IfcFootingType,
IfcPileType,
IfcBuildingElementProxyType,
IfcAlignment,
IfcAlignmentCant,
IfcAlignmentHorizontal,
IfcAlignmentVertical,
IfcAlignmentSegment,
IfcRoad,
IfcRoadPart,
IfcBridge,
IfcBridgePart,
IfcRailway,
IfcRailwayPart,
IfcFacility,
IfcFacilityPart,
IfcGeotechnicalElement,
IfcBorehole,
IfcGeomodel,
IfcGeoslice,
IfcSolidStratum,
IfcVoidStratum,
IfcWaterStratum,
IfcEarthworksCut,
IfcEarthworksFill,
IfcEarthworksElement,
IfcPavement,
IfcCourse,
IfcKerb,
IfcDeepFoundation,
Unknown(String),
}
impl FromStr for IfcType {
type Err = std::convert::Infallible;
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
Ok(Self::parse(s))
}
}
impl IfcType {
pub fn parse(s: &str) -> Self {
match s.to_uppercase().as_str() {
"IFCPROJECT" => IfcType::IfcProject,
"IFCSITE" => IfcType::IfcSite,
"IFCBUILDING" => IfcType::IfcBuilding,
"IFCBUILDINGSTOREY" => IfcType::IfcBuildingStorey,
"IFCSPACE" => IfcType::IfcSpace,
"IFCWALL" => IfcType::IfcWall,
"IFCWALLSTANDARDCASE" => IfcType::IfcWallStandardCase,
"IFCCURTAINWALL" => IfcType::IfcCurtainWall,
"IFCSLAB" => IfcType::IfcSlab,
"IFCROOF" => IfcType::IfcRoof,
"IFCBEAM" => IfcType::IfcBeam,
"IFCCOLUMN" => IfcType::IfcColumn,
"IFCDOOR" => IfcType::IfcDoor,
"IFCWINDOW" => IfcType::IfcWindow,
"IFCSTAIR" => IfcType::IfcStair,
"IFCSTAIRFLIGHT" => IfcType::IfcStairFlight,
"IFCRAMP" => IfcType::IfcRamp,
"IFCRAMPFLIGHT" => IfcType::IfcRampFlight,
"IFCRAILING" => IfcType::IfcRailing,
"IFCCOVERING" => IfcType::IfcCovering,
"IFCPLATE" => IfcType::IfcPlate,
"IFCMEMBER" => IfcType::IfcMember,
"IFCFOOTING" => IfcType::IfcFooting,
"IFCPILE" => IfcType::IfcPile,
"IFCBUILDINGELEMENTPROXY" => IfcType::IfcBuildingElementProxy,
"IFCELEMENTASSEMBLY" => IfcType::IfcElementAssembly,
"IFCDISTRIBUTIONELEMENT" => IfcType::IfcDistributionElement,
"IFCDISTRIBUTIONFLOWELEMENT" => IfcType::IfcDistributionFlowElement,
"IFCFLOWTERMINAL" => IfcType::IfcFlowTerminal,
"IFCFLOWSEGMENT" => IfcType::IfcFlowSegment,
"IFCFLOWFITTING" => IfcType::IfcFlowFitting,
"IFCFLOWCONTROLLER" => IfcType::IfcFlowController,
"IFCFLOWMOVINGDEVICE" => IfcType::IfcFlowMovingDevice,
"IFCFLOWSTORAGEDEVICE" => IfcType::IfcFlowStorageDevice,
"IFCFLOWTREATMENTDEVICE" => IfcType::IfcFlowTreatmentDevice,
"IFCENERGYCONVERSIONDEVICE" => IfcType::IfcEnergyConversionDevice,
"IFCDISTRIBUTIONCONTROLELEMENT" => IfcType::IfcDistributionControlElement,
"IFCCABLESEGMENT" => IfcType::IfcCableSegment,
"IFCCABLECARRIERSEGMENT" => IfcType::IfcCableCarrierSegment,
"IFCCABLECARRIERFITTING" => IfcType::IfcCableCarrierFitting,
"IFCPIPESEGMENT" => IfcType::IfcPipeSegment,
"IFCPIPEFITTING" => IfcType::IfcPipeFitting,
"IFCSPACEHEATER" => IfcType::IfcSpaceHeater,
"IFCAIRTERMINAL" => IfcType::IfcAirTerminal,
"IFCFURNISHINGELEMENT" => IfcType::IfcFurnishingElement,
"IFCFURNITURE" => IfcType::IfcFurniture,
"IFCSYSTEMFURNITUREELEMENT" => IfcType::IfcSystemFurnitureElement,
"IFCOPENINGELEMENT" => IfcType::IfcOpeningElement,
"IFCOPENINGSTANDARDCASE" => IfcType::IfcOpeningStandardCase,
"IFCVOIDINGFEATURE" => IfcType::IfcVoidingFeature,
"IFCPROJECTIONELEMENT" => IfcType::IfcProjectionElement,
"IFCEXTRUDEDAREASOLID" => IfcType::IfcExtrudedAreaSolid,
"IFCEXTRUDEDAREASOLIDTAPERED" => IfcType::IfcExtrudedAreaSolidTapered,
"IFCREVOLVEDAREASOLID" => IfcType::IfcRevolvedAreaSolid,
"IFCREVOLVEDAREASOLIDTAPERED" => IfcType::IfcRevolvedAreaSolidTapered,
"IFCSWEPTDISKSOLID" => IfcType::IfcSweptDiskSolid,
"IFCSWEPTDISKSOLIDPOLYGONAL" => IfcType::IfcSweptDiskSolidPolygonal,
"IFCSURFACECURVESWEPTAREASOLID" => IfcType::IfcSurfaceCurveSweptAreaSolid,
"IFCFIXEDREFERENCESWEPTAREASOLID" => IfcType::IfcFixedReferenceSweptAreaSolid,
"IFCFACETEDBREP" => IfcType::IfcFacetedBrep,
"IFCFACETEDBREPWITHVOIDS" => IfcType::IfcFacetedBrepWithVoids,
"IFCADVANCEDBREP" => IfcType::IfcAdvancedBrep,
"IFCADVANCEDBREPWITHVOIDS" => IfcType::IfcAdvancedBrepWithVoids,
"IFCTRIANGULATEDFACESET" => IfcType::IfcTriangulatedFaceSet,
"IFCPOLYGONALFACESET" => IfcType::IfcPolygonalFaceSet,
"IFCTESSELLATEDFACESET" => IfcType::IfcTessellatedFaceSet,
"IFCBOOLEANRESULT" => IfcType::IfcBooleanResult,
"IFCBOOLEANCLIPPINGRESULT" => IfcType::IfcBooleanClippingResult,
"IFCMAPPEDITEM" => IfcType::IfcMappedItem,
"IFCREPRESENTATIONMAP" => IfcType::IfcRepresentationMap,
"IFCBLOCK" => IfcType::IfcBlock,
"IFCRECTANGULARPYRAMID" => IfcType::IfcRectangularPyramid,
"IFCRIGHTCIRCULARCONE" => IfcType::IfcRightCircularCone,
"IFCRIGHTCIRCULARCYLINDER" => IfcType::IfcRightCircularCylinder,
"IFCSPHERE" => IfcType::IfcSphere,
"IFCHALFSPACESOLID" => IfcType::IfcHalfSpaceSolid,
"IFCPOLYGONALBOUNDEDHALFSPACE" => IfcType::IfcPolygonalBoundedHalfSpace,
"IFCBOXEDHALFSPACE" => IfcType::IfcBoxedHalfSpace,
"IFCARBITRARYCLOSEDPROFILEDEF" => IfcType::IfcArbitraryClosedProfileDef,
"IFCARBITRARYPROFILEDEFWITHVOIDS" => IfcType::IfcArbitraryProfileDefWithVoids,
"IFCRECTANGLEPROFILEDEF" => IfcType::IfcRectangleProfileDef,
"IFCRECTANGLEHOLLOWPROFILEDEF" => IfcType::IfcRectangleHollowProfileDef,
"IFCCIRCLEPROFILEDEF" => IfcType::IfcCircleProfileDef,
"IFCCIRCLEHOLLOWPROFILEDEF" => IfcType::IfcCircleHollowProfileDef,
"IFCELLIPSEPROFILEDEF" => IfcType::IfcEllipseProfileDef,
"IFCISHAPEPROFILEDEF" => IfcType::IfcIShapeProfileDef,
"IFCLSHAPEPROFILEDEF" => IfcType::IfcLShapeProfileDef,
"IFCTSHAPEPROFILEDEF" => IfcType::IfcTShapeProfileDef,
"IFCUSHAPEPROFILEDEF" => IfcType::IfcUShapeProfileDef,
"IFCCSHAPEPROFILEDEF" => IfcType::IfcCShapeProfileDef,
"IFCZSHAPEPROFILEDEF" => IfcType::IfcZShapeProfileDef,
"IFCASYMMETRICISHAPEPROFILEDEF" => IfcType::IfcAsymmetricIShapeProfileDef,
"IFCTRAPEZIUMPROFILEDEF" => IfcType::IfcTrapeziumProfileDef,
"IFCCOMPOSITEPROFILEDEF" => IfcType::IfcCompositeProfileDef,
"IFCDERIVEDPROFILEDEF" => IfcType::IfcDerivedProfileDef,
"IFCCENTERLINEPROFILEDEF" => IfcType::IfcCenterLineProfileDef,
"IFCPOLYLINE" => IfcType::IfcPolyline,
"IFCCOMPOSITECURVE" => IfcType::IfcCompositeCurve,
"IFCCOMPOSITECURVESEGMENT" => IfcType::IfcCompositeCurveSegment,
"IFCTRIMMEDCURVE" => IfcType::IfcTrimmedCurve,
"IFCCIRCLE" => IfcType::IfcCircle,
"IFCELLIPSE" => IfcType::IfcEllipse,
"IFCLINE" => IfcType::IfcLine,
"IFCBSPLINECURVE" => IfcType::IfcBSplineCurve,
"IFCBSPLINECURVEWITHKNOTS" => IfcType::IfcBSplineCurveWithKnots,
"IFCRATIONALBSPLINECURVEWITHKNOTS" => IfcType::IfcRationalBSplineCurveWithKnots,
"IFCINDEXEDPOLYCURVE" => IfcType::IfcIndexedPolyCurve,
"IFCPLANE" => IfcType::IfcPlane,
"IFCCURVEBOUNDEDPLANE" => IfcType::IfcCurveBoundedPlane,
"IFCCYLINDRICALSURFACE" => IfcType::IfcCylindricalSurface,
"IFCBSPLINESURFACE" => IfcType::IfcBSplineSurface,
"IFCBSPLINESURFACEWITHKNOTS" => IfcType::IfcBSplineSurfaceWithKnots,
"IFCRATIONALBSPLINESURFACEWITHKNOTS" => IfcType::IfcRationalBSplineSurfaceWithKnots,
"IFCCARTESIANPOINT" => IfcType::IfcCartesianPoint,
"IFCDIRECTION" => IfcType::IfcDirection,
"IFCVECTOR" => IfcType::IfcVector,
"IFCCARTESIANPOINTLIST2D" => IfcType::IfcCartesianPointList2D,
"IFCCARTESIANPOINTLIST3D" => IfcType::IfcCartesianPointList3D,
"IFCAXIS2PLACEMENT2D" => IfcType::IfcAxis2Placement2D,
"IFCAXIS2PLACEMENT3D" => IfcType::IfcAxis2Placement3D,
"IFCLOCALPLACEMENT" => IfcType::IfcLocalPlacement,
"IFCCARTESIANTRANSFORMATIONOPERATOR3D" => IfcType::IfcCartesianTransformationOperator3D,
"IFCCARTESIANTRANSFORMATIONOPERATOR3DNONUNIFORM" => {
IfcType::IfcCartesianTransformationOperator3DnonUniform
}
"IFCSHAPEREPRESENTATION" => IfcType::IfcShapeRepresentation,
"IFCPRODUCTDEFINITIONSHAPE" => IfcType::IfcProductDefinitionShape,
"IFCGEOMETRICREPRESENTATIONCONTEXT" => IfcType::IfcGeometricRepresentationContext,
"IFCGEOMETRICREPRESENTATIONSUBCONTEXT" => IfcType::IfcGeometricRepresentationSubContext,
"IFCCLOSEDSHELL" => IfcType::IfcClosedShell,
"IFCOPENSHELL" => IfcType::IfcOpenShell,
"IFCFACE" => IfcType::IfcFace,
"IFCFACEBOUND" => IfcType::IfcFaceBound,
"IFCFACEOUTERBOUND" => IfcType::IfcFaceOuterBound,
"IFCPOLYLOOP" => IfcType::IfcPolyLoop,
"IFCEDGELOOP" => IfcType::IfcEdgeLoop,
"IFCORIENTEDEDGE" => IfcType::IfcOrientedEdge,
"IFCEDGECURVE" => IfcType::IfcEdgeCurve,
"IFCVERTEXPOINT" => IfcType::IfcVertexPoint,
"IFCCONNECTEDFACESET" => IfcType::IfcConnectedFaceSet,
"IFCRELCONTAINEDINSPATIALSTRUCTURE" => IfcType::IfcRelContainedInSpatialStructure,
"IFCRELAGGREGATES" => IfcType::IfcRelAggregates,
"IFCRELDEFINESBYPROPERTIES" => IfcType::IfcRelDefinesByProperties,
"IFCRELDEFINESBYTYPE" => IfcType::IfcRelDefinesByType,
"IFCRELASSOCIATESMATERIAL" => IfcType::IfcRelAssociatesMaterial,
"IFCRELVOIDSELEMENT" => IfcType::IfcRelVoidsElement,
"IFCRELFILLSELEMENT" => IfcType::IfcRelFillsElement,
"IFCRELCONNECTSPATHELEMENTS" => IfcType::IfcRelConnectsPathElements,
"IFCRELSPACEBOUNDARY" => IfcType::IfcRelSpaceBoundary,
"IFCRELASSIGNSTOGROUP" => IfcType::IfcRelAssignsToGroup,
"IFCPROPERTYSET" => IfcType::IfcPropertySet,
"IFCPROPERTYSINGLEVALUE" => IfcType::IfcPropertySingleValue,
"IFCPROPERTYENUMERATEDVALUE" => IfcType::IfcPropertyEnumeratedValue,
"IFCPROPERTYBOUNDEDVALUE" => IfcType::IfcPropertyBoundedValue,
"IFCPROPERTYLISTVALUE" => IfcType::IfcPropertyListValue,
"IFCPROPERTYTABLEVALUE" => IfcType::IfcPropertyTableValue,
"IFCCOMPLEXPROPERTY" => IfcType::IfcComplexProperty,
"IFCELEMENTQUANTITY" => IfcType::IfcElementQuantity,
"IFCQUANTITYLENGTH" => IfcType::IfcQuantityLength,
"IFCQUANTITYAREA" => IfcType::IfcQuantityArea,
"IFCQUANTITYVOLUME" => IfcType::IfcQuantityVolume,
"IFCQUANTITYCOUNT" => IfcType::IfcQuantityCount,
"IFCQUANTITYWEIGHT" => IfcType::IfcQuantityWeight,
"IFCQUANTITYTIME" => IfcType::IfcQuantityTime,
"IFCMATERIAL" => IfcType::IfcMaterial,
"IFCMATERIALLAYER" => IfcType::IfcMaterialLayer,
"IFCMATERIALLAYERSET" => IfcType::IfcMaterialLayerSet,
"IFCMATERIALLAYERSETUSAGE" => IfcType::IfcMaterialLayerSetUsage,
"IFCMATERIALLIST" => IfcType::IfcMaterialList,
"IFCMATERIALCONSTITUENTSET" => IfcType::IfcMaterialConstituentSet,
"IFCMATERIALCONSTITUENT" => IfcType::IfcMaterialConstituent,
"IFCMATERIALPROFILE" => IfcType::IfcMaterialProfile,
"IFCMATERIALPROFILESET" => IfcType::IfcMaterialProfileSet,
"IFCMATERIALPROFILESETUSAGE" => IfcType::IfcMaterialProfileSetUsage,
"IFCSTYLEDITEM" => IfcType::IfcStyledItem,
"IFCSURFACESTYLE" => IfcType::IfcSurfaceStyle,
"IFCSURFACESTYLERENDERING" => IfcType::IfcSurfaceStyleRendering,
"IFCCOLOURRGB" => IfcType::IfcColourRgb,
"IFCPRESENTATIONLAYERASSIGNMENT" => IfcType::IfcPresentationLayerAssignment,
"IFCLIGHTFIXTURE" => IfcType::IfcLightFixture,
"IFCLIGHTFIXTURETYPE" => IfcType::IfcLightFixtureType,
"IFCLIGHTSOURCE" => IfcType::IfcLightSource,
"IFCLIGHTSOURCEAMBIENT" => IfcType::IfcLightSourceAmbient,
"IFCLIGHTSOURCEDIRECTIONAL" => IfcType::IfcLightSourceDirectional,
"IFCLIGHTSOURCEGONIOMETRIC" => IfcType::IfcLightSourceGoniometric,
"IFCLIGHTSOURCEPOSITIONAL" => IfcType::IfcLightSourcePositional,
"IFCLIGHTSOURCESPOT" => IfcType::IfcLightSourceSpot,
"IFCLIGHTINTENSITYDISTRIBUTION" => IfcType::IfcLightIntensityDistribution,
"IFCLIGHTDISTRIBUTIONDATA" => IfcType::IfcLightDistributionData,
"IFCUNITASSIGNMENT" => IfcType::IfcUnitAssignment,
"IFCSIUNIT" => IfcType::IfcSIUnit,
"IFCCONVERSIONBASEDUNIT" => IfcType::IfcConversionBasedUnit,
"IFCDERIVEDUNIT" => IfcType::IfcDerivedUnit,
"IFCMEASUREWITHUNIT" => IfcType::IfcMeasureWithUnit,
"IFCWALLTYPE" => IfcType::IfcWallType,
"IFCSLABTYPE" => IfcType::IfcSlabType,
"IFCBEAMTYPE" => IfcType::IfcBeamType,
"IFCCOLUMNTYPE" => IfcType::IfcColumnType,
"IFCDOORTYPE" => IfcType::IfcDoorType,
"IFCWINDOWTYPE" => IfcType::IfcWindowType,
"IFCCOVERINGTYPE" => IfcType::IfcCoveringType,
"IFCRAILINGTYPE" => IfcType::IfcRailingType,
"IFCSTAIRTYPE" => IfcType::IfcStairType,
"IFCSTAIRFLIGHTTYPE" => IfcType::IfcStairFlightType,
"IFCRAMPTYPE" => IfcType::IfcRampType,
"IFCRAMPFLIGHTTYPE" => IfcType::IfcRampFlightType,
"IFCROOFTYPE" => IfcType::IfcRoofType,
"IFCMEMBERTYPE" => IfcType::IfcMemberType,
"IFCPLATETYPE" => IfcType::IfcPlateType,
"IFCFOOTINGTYPE" => IfcType::IfcFootingType,
"IFCPILETYPE" => IfcType::IfcPileType,
"IFCBUILDINGELEMENTPROXYTYPE" => IfcType::IfcBuildingElementProxyType,
"IFCALIGNMENT" => IfcType::IfcAlignment,
"IFCALIGNMENTCANT" => IfcType::IfcAlignmentCant,
"IFCALIGNMENTHORIZONTAL" => IfcType::IfcAlignmentHorizontal,
"IFCALIGNMENTVERTICAL" => IfcType::IfcAlignmentVertical,
"IFCALIGNMENTSEGMENT" => IfcType::IfcAlignmentSegment,
"IFCROAD" => IfcType::IfcRoad,
"IFCROADPART" => IfcType::IfcRoadPart,
"IFCBRIDGE" => IfcType::IfcBridge,
"IFCBRIDGEPART" => IfcType::IfcBridgePart,
"IFCRAILWAY" => IfcType::IfcRailway,
"IFCRAILWAYPART" => IfcType::IfcRailwayPart,
"IFCFACILITY" => IfcType::IfcFacility,
"IFCFACILITYPART" => IfcType::IfcFacilityPart,
"IFCGEOTECHNICALELEMENT" => IfcType::IfcGeotechnicalElement,
"IFCBOREHOLE" => IfcType::IfcBorehole,
"IFCGEOMODEL" => IfcType::IfcGeomodel,
"IFCGEOSLICE" => IfcType::IfcGeoslice,
"IFCSOLIDSTRATUM" => IfcType::IfcSolidStratum,
"IFCVOIDSTRATUM" => IfcType::IfcVoidStratum,
"IFCWATERSTRATUM" => IfcType::IfcWaterStratum,
"IFCEARTHWORKSCUT" => IfcType::IfcEarthworksCut,
"IFCEARTHWORKSFILL" => IfcType::IfcEarthworksFill,
"IFCEARTHWORKSELEMENT" => IfcType::IfcEarthworksElement,
"IFCPAVEMENT" => IfcType::IfcPavement,
"IFCCOURSE" => IfcType::IfcCourse,
"IFCKERB" => IfcType::IfcKerb,
"IFCDEEPFOUNDATION" => IfcType::IfcDeepFoundation,
_ => IfcType::Unknown(s.to_string()),
}
}
pub fn name(&self) -> &str {
match self {
IfcType::Unknown(s) => s,
_ => {
match self {
IfcType::IfcProject => "IFCPROJECT",
IfcType::IfcSite => "IFCSITE",
IfcType::IfcBuilding => "IFCBUILDING",
IfcType::IfcBuildingStorey => "IFCBUILDINGSTOREY",
IfcType::IfcSpace => "IFCSPACE",
IfcType::IfcWall => "IFCWALL",
IfcType::IfcWallStandardCase => "IFCWALLSTANDARDCASE",
IfcType::IfcCurtainWall => "IFCCURTAINWALL",
IfcType::IfcSlab => "IFCSLAB",
IfcType::IfcRoof => "IFCROOF",
IfcType::IfcBeam => "IFCBEAM",
IfcType::IfcColumn => "IFCCOLUMN",
IfcType::IfcDoor => "IFCDOOR",
IfcType::IfcWindow => "IFCWINDOW",
IfcType::IfcStair => "IFCSTAIR",
IfcType::IfcStairFlight => "IFCSTAIRFLIGHT",
IfcType::IfcRamp => "IFCRAMP",
IfcType::IfcRampFlight => "IFCRAMPFLIGHT",
IfcType::IfcRailing => "IFCRAILING",
IfcType::IfcCovering => "IFCCOVERING",
IfcType::IfcPlate => "IFCPLATE",
IfcType::IfcMember => "IFCMEMBER",
IfcType::IfcFooting => "IFCFOOTING",
IfcType::IfcPile => "IFCPILE",
IfcType::IfcBuildingElementProxy => "IFCBUILDINGELEMENTPROXY",
IfcType::IfcElementAssembly => "IFCELEMENTASSEMBLY",
IfcType::IfcExtrudedAreaSolid => "IFCEXTRUDEDAREASOLID",
IfcType::IfcFacetedBrep => "IFCFACETEDBREP",
IfcType::IfcTriangulatedFaceSet => "IFCTRIANGULATEDFACESET",
IfcType::IfcMappedItem => "IFCMAPPEDITEM",
IfcType::IfcBooleanClippingResult => "IFCBOOLEANCLIPPINGRESULT",
IfcType::IfcFurnishingElement => "IFCFURNISHINGELEMENT",
IfcType::IfcFurniture => "IFCFURNITURE",
IfcType::IfcFlowTerminal => "IFCFLOWTERMINAL",
IfcType::IfcFlowSegment => "IFCFLOWSEGMENT",
IfcType::IfcFlowFitting => "IFCFLOWFITTING",
IfcType::IfcFlowController => "IFCFLOWCONTROLLER",
IfcType::IfcCableSegment => "IFCCABLESEGMENT",
IfcType::IfcCableCarrierSegment => "IFCCABLECARRIERSEGMENT",
IfcType::IfcCableCarrierFitting => "IFCCABLECARRIERFITTING",
IfcType::IfcPipeSegment => "IFCPIPESEGMENT",
IfcType::IfcPipeFitting => "IFCPIPEFITTING",
IfcType::IfcSpaceHeater => "IFCSPACEHEATER",
IfcType::IfcAirTerminal => "IFCAIRTERMINAL",
IfcType::IfcDistributionElement => "IFCDISTRIBUTIONELEMENT",
IfcType::IfcOpeningElement => "IFCOPENINGELEMENT",
IfcType::IfcLightFixture => "IFCLIGHTFIXTURE",
IfcType::IfcLightFixtureType => "IFCLIGHTFIXTURETYPE",
IfcType::IfcLightSourceGoniometric => "IFCLIGHTSOURCEGONIOMETRIC",
IfcType::IfcLightSourcePositional => "IFCLIGHTSOURCEPOSITIONAL",
IfcType::IfcLightSourceSpot => "IFCLIGHTSOURCESPOT",
IfcType::IfcLightSourceDirectional => "IFCLIGHTSOURCEDIRECTIONAL",
IfcType::IfcLightSourceAmbient => "IFCLIGHTSOURCEAMBIENT",
_ => "UNKNOWN",
}
}
}
}
pub fn parent(&self) -> Option<Self> {
use IfcType::*;
Some(match self {
IfcObjectDefinition => IfcRoot,
IfcObject => IfcObjectDefinition,
IfcProduct => IfcObject,
IfcSpatialElement => IfcProduct,
IfcSpatialStructureElement => IfcSpatialElement,
IfcExternalSpatialStructureElement => IfcSpatialElement,
IfcExternalSpatialElement => IfcExternalSpatialStructureElement,
IfcSpatialZone => IfcSpatialElement,
IfcSite => IfcSpatialStructureElement,
IfcBuilding => IfcSpatialStructureElement,
IfcBuildingStorey => IfcSpatialStructureElement,
IfcSpace => IfcSpatialStructureElement,
IfcFacility => IfcSpatialStructureElement,
IfcFacilityPart => IfcSpatialStructureElement,
IfcBridge => IfcFacility,
IfcBridgePart => IfcFacilityPart,
IfcRoad => IfcFacility,
IfcRoadPart => IfcFacilityPart,
IfcRailway => IfcFacility,
IfcRailwayPart => IfcFacilityPart,
IfcElement => IfcProduct,
IfcBuiltElement => IfcElement,
IfcCivilElement => IfcElement,
IfcGeographicElement => IfcElement,
IfcAnnotation => IfcProduct,
IfcPort => IfcProduct,
IfcElementAssembly => IfcElement,
IfcFurnishingElement => IfcElement,
IfcFurniture => IfcFurnishingElement,
IfcSystemFurnitureElement => IfcFurnishingElement,
IfcBuildingElementProxy => IfcBuiltElement,
IfcWall => IfcBuiltElement,
IfcWallStandardCase => IfcWall,
IfcCurtainWall => IfcBuiltElement,
IfcSlab => IfcBuiltElement,
IfcRoof => IfcBuiltElement,
IfcBeam => IfcBuiltElement,
IfcColumn => IfcBuiltElement,
IfcDoor => IfcBuiltElement,
IfcWindow => IfcBuiltElement,
IfcStair => IfcBuiltElement,
IfcStairFlight => IfcBuiltElement,
IfcRamp => IfcBuiltElement,
IfcRampFlight => IfcBuiltElement,
IfcRailing => IfcBuiltElement,
IfcCovering => IfcBuiltElement,
IfcPlate => IfcBuiltElement,
IfcMember => IfcBuiltElement,
IfcFooting => IfcBuiltElement,
IfcPile => IfcBuiltElement,
IfcDeepFoundation => IfcBuiltElement,
IfcFeatureElement => IfcElement,
IfcFeatureElementSubtraction => IfcFeatureElement,
IfcFeatureElementAddition => IfcFeatureElement,
IfcOpeningElement => IfcFeatureElementSubtraction,
IfcOpeningStandardCase => IfcOpeningElement,
IfcVoidingFeature => IfcFeatureElementSubtraction,
IfcProjectionElement => IfcFeatureElementAddition,
IfcDistributionElement => IfcElement,
IfcDistributionFlowElement => IfcDistributionElement,
IfcDistributionControlElement => IfcDistributionElement,
IfcFlowSegment => IfcDistributionFlowElement,
IfcFlowFitting => IfcDistributionFlowElement,
IfcFlowTerminal => IfcDistributionFlowElement,
IfcFlowController => IfcDistributionFlowElement,
IfcFlowMovingDevice => IfcDistributionFlowElement,
IfcFlowStorageDevice => IfcDistributionFlowElement,
IfcFlowTreatmentDevice => IfcDistributionFlowElement,
IfcEnergyConversionDevice => IfcDistributionFlowElement,
IfcCableSegment => IfcFlowSegment,
IfcCableCarrierSegment => IfcFlowSegment,
IfcCableCarrierFitting => IfcFlowFitting,
IfcPipeSegment => IfcFlowSegment,
IfcPipeFitting => IfcFlowFitting,
IfcSpaceHeater => IfcEnergyConversionDevice,
IfcAirTerminal => IfcFlowTerminal,
IfcLightFixture => IfcFlowTerminal,
IfcGeotechnicalElement => IfcElement,
IfcGeotechnicalAssembly => IfcGeotechnicalElement,
IfcBorehole => IfcGeotechnicalAssembly,
IfcGeomodel => IfcGeotechnicalAssembly,
IfcGeoslice => IfcGeotechnicalAssembly,
IfcSolidStratum => IfcGeotechnicalElement,
IfcVoidStratum => IfcGeotechnicalElement,
IfcWaterStratum => IfcGeotechnicalElement,
IfcEarthworksElement => IfcElement,
IfcEarthworksCut => IfcFeatureElementSubtraction,
IfcEarthworksFill => IfcEarthworksElement,
IfcPavement => IfcBuiltElement,
IfcCourse => IfcBuiltElement,
IfcKerb => IfcBuiltElement,
_ => return None,
})
}
pub fn is_subtype_of(&self, parent: IfcType) -> bool {
if matches!(self, IfcType::Unknown(_)) {
return false;
}
let mut current = Some(self.clone());
while let Some(t) = current {
if t == parent {
return true;
}
current = t.parent();
}
false
}
pub fn has_geometry(&self) -> bool {
if !self.is_subtype_of(IfcType::IfcProduct) {
return false;
}
!is_non_geometric_spatial(self)
}
}
fn is_non_geometric_spatial(t: &IfcType) -> bool {
if matches!(t, IfcType::IfcSpace | IfcType::IfcSite) {
return false;
}
t.is_subtype_of(IfcType::IfcSpatialElement)
}
impl IfcType {
pub fn is_spatial(&self) -> bool {
matches!(
self,
IfcType::IfcProject
| IfcType::IfcSite
| IfcType::IfcBuilding
| IfcType::IfcBuildingStorey
| IfcType::IfcSpace
| IfcType::IfcFacility
| IfcType::IfcFacilityPart
)
}
}
impl Default for IfcType {
fn default() -> Self {
IfcType::Unknown(String::new())
}
}
impl fmt::Display for IfcType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.name())
}
}
#[derive(Clone, Debug, PartialEq, Default)]
pub enum AttributeValue {
#[default]
Null,
Derived,
EntityRef(EntityId),
Bool(bool),
Integer(i64),
Float(f64),
String(String),
Enum(String),
List(Vec<AttributeValue>),
TypedValue(String, Vec<AttributeValue>),
}
impl AttributeValue {
pub fn as_entity_ref(&self) -> Option<EntityId> {
match self {
AttributeValue::EntityRef(id) => Some(*id),
_ => None,
}
}
pub fn as_string(&self) -> Option<&str> {
match self {
AttributeValue::String(s) => Some(s),
AttributeValue::TypedValue(_, args) if !args.is_empty() => args[0].as_string(),
_ => None,
}
}
pub fn as_float(&self) -> Option<f64> {
match self {
AttributeValue::Float(f) => Some(*f),
AttributeValue::Integer(i) => Some(*i as f64),
AttributeValue::TypedValue(_, args) if !args.is_empty() => args[0].as_float(),
_ => None,
}
}
pub fn as_integer(&self) -> Option<i64> {
match self {
AttributeValue::Integer(i) => Some(*i),
_ => None,
}
}
pub fn as_bool(&self) -> Option<bool> {
match self {
AttributeValue::Bool(b) => Some(*b),
AttributeValue::Enum(s) => match s.to_uppercase().as_str() {
"TRUE" | "T" => Some(true),
"FALSE" | "F" => Some(false),
_ => None,
},
_ => None,
}
}
pub fn as_enum(&self) -> Option<&str> {
match self {
AttributeValue::Enum(s) => Some(s),
_ => None,
}
}
pub fn as_list(&self) -> Option<&[AttributeValue]> {
match self {
AttributeValue::List(list) => Some(list),
_ => None,
}
}
pub fn is_null(&self) -> bool {
matches!(self, AttributeValue::Null)
}
pub fn is_derived(&self) -> bool {
matches!(self, AttributeValue::Derived)
}
}
#[derive(Clone, Debug)]
pub struct DecodedEntity {
pub id: EntityId,
pub ifc_type: IfcType,
pub attributes: Vec<AttributeValue>,
}
impl DecodedEntity {
pub fn get(&self, index: usize) -> Option<&AttributeValue> {
self.attributes.get(index)
}
pub fn get_ref(&self, index: usize) -> Option<EntityId> {
self.get(index).and_then(|v| v.as_entity_ref())
}
pub fn get_string(&self, index: usize) -> Option<&str> {
self.get(index).and_then(|v| v.as_string())
}
pub fn get_float(&self, index: usize) -> Option<f64> {
self.get(index).and_then(|v| v.as_float())
}
pub fn get_integer(&self, index: usize) -> Option<i64> {
self.get(index).and_then(|v| v.as_integer())
}
pub fn get_list(&self, index: usize) -> Option<&[AttributeValue]> {
self.get(index).and_then(|v| v.as_list())
}
pub fn get_bool(&self, index: usize) -> Option<bool> {
self.get(index).and_then(|v| v.as_bool())
}
pub fn get_enum(&self, index: usize) -> Option<&str> {
self.get(index).and_then(|v| v.as_enum())
}
pub fn get_refs(&self, index: usize) -> Option<Vec<EntityId>> {
self.get_list(index)
.map(|list| list.iter().filter_map(|v| v.as_entity_ref()).collect())
}
}
#[derive(Clone, Debug, Default)]
pub struct MeshData {
pub positions: Vec<f32>,
pub normals: Vec<f32>,
pub indices: Vec<u32>,
}
impl MeshData {
pub fn new() -> Self {
Self::default()
}
pub fn with_capacity(vertex_count: usize, index_count: usize) -> Self {
Self {
positions: Vec::with_capacity(vertex_count * 3),
normals: Vec::with_capacity(vertex_count * 3),
indices: Vec::with_capacity(index_count),
}
}
pub fn is_empty(&self) -> bool {
self.positions.is_empty()
}
pub fn vertex_count(&self) -> usize {
self.positions.len() / 3
}
pub fn triangle_count(&self) -> usize {
self.indices.len() / 3
}
pub fn merge(&mut self, other: &MeshData) {
let vertex_offset = self.vertex_count() as u32;
self.positions.extend_from_slice(&other.positions);
self.normals.extend_from_slice(&other.normals);
self.indices
.extend(other.indices.iter().map(|i| i + vertex_offset));
}
}
#[derive(Clone, Debug, Default)]
pub struct ModelMetadata {
pub schema_version: String,
pub originating_system: Option<String>,
pub preprocessor_version: Option<String>,
pub file_name: Option<String>,
pub file_description: Option<String>,
pub author: Option<String>,
pub organization: Option<String>,
pub timestamp: Option<String>,
}
#[cfg(test)]
mod inheritance_tests {
use super::IfcType;
#[test]
fn building_elements_have_geometry() {
for t in [
IfcType::IfcWall,
IfcType::IfcWallStandardCase,
IfcType::IfcSlab,
IfcType::IfcBeam,
IfcType::IfcColumn,
IfcType::IfcDoor,
IfcType::IfcWindow,
IfcType::IfcRoof,
IfcType::IfcStair,
] {
assert!(t.has_geometry(), "{t:?} should have geometry");
}
}
#[test]
fn mep_elements_have_geometry() {
for t in [
IfcType::IfcFlowSegment,
IfcType::IfcFlowFitting,
IfcType::IfcEnergyConversionDevice,
IfcType::IfcFlowTreatmentDevice,
IfcType::IfcCableSegment,
IfcType::IfcCableCarrierSegment,
IfcType::IfcCableCarrierFitting,
IfcType::IfcPipeSegment,
IfcType::IfcPipeFitting,
IfcType::IfcSpaceHeater,
IfcType::IfcAirTerminal,
IfcType::IfcLightFixture,
] {
assert!(t.has_geometry(), "{t:?} should have geometry");
}
}
#[test]
fn space_and_site_have_geometry() {
assert!(IfcType::IfcSpace.has_geometry());
assert!(IfcType::IfcSite.has_geometry());
assert!(IfcType::IfcOpeningElement.has_geometry());
}
#[test]
fn non_geometric_spatial_excluded() {
for t in [
IfcType::IfcBuilding,
IfcType::IfcBuildingStorey,
IfcType::IfcFacility,
IfcType::IfcFacilityPart,
IfcType::IfcSpatialElement,
IfcType::IfcSpatialStructureElement,
IfcType::IfcBridge,
IfcType::IfcRoad,
IfcType::IfcRailway,
IfcType::IfcBridgePart,
IfcType::IfcSpatialZone,
IfcType::IfcExternalSpatialElement,
IfcType::IfcExternalSpatialStructureElement,
] {
assert!(!t.has_geometry(), "{t:?} should NOT have geometry");
}
}
#[test]
fn non_products_excluded() {
for t in [
IfcType::IfcProject,
IfcType::IfcMaterial,
IfcType::IfcPropertySet,
IfcType::IfcRelAggregates,
IfcType::IfcSurfaceStyleRendering,
IfcType::IfcCartesianPoint,
IfcType::IfcExtrudedAreaSolid,
] {
assert!(!t.has_geometry(), "{t:?} should NOT have geometry");
}
}
#[test]
fn is_subtype_of_walks_chain() {
assert!(IfcType::IfcWall.is_subtype_of(IfcType::IfcBuiltElement));
assert!(IfcType::IfcCableSegment.is_subtype_of(IfcType::IfcElement));
assert!(IfcType::IfcCableSegment.is_subtype_of(IfcType::IfcProduct));
assert!(IfcType::IfcWall.is_subtype_of(IfcType::IfcWall));
assert!(!IfcType::IfcWall.is_subtype_of(IfcType::IfcDistributionElement));
assert!(!IfcType::Unknown("FOO".into()).is_subtype_of(IfcType::IfcProduct));
}
#[test]
fn mep_concrete_types_inherit_geometry() {
for t in [
IfcType::IfcCableSegment,
IfcType::IfcCableCarrierSegment,
IfcType::IfcCableCarrierFitting,
IfcType::IfcPipeSegment,
IfcType::IfcPipeFitting,
IfcType::IfcSpaceHeater,
IfcType::IfcAirTerminal,
] {
assert!(
t.has_geometry(),
"{t:?} should inherit geometry via parent() chain"
);
}
}
}