Fix #1300. New IfcOpenShell.util.type module for checking applicable type classes.

This commit is contained in:
Dion Moult
2021-02-13 18:27:02 +11:00
parent 7de3eec1b1
commit e4dee2258d
4 changed files with 882 additions and 0 deletions
@@ -0,0 +1,100 @@
# See bug #1300. Dodgy quick results that we should rebuild later.
import json
import ifcopenshell
import ifcopenshell.util.schema
filepath = "IFC4.exp"
schema2x3 = ifcopenshell.ifcopenshell_wrapper.schema_by_name("IFC2X3")
schema4 = ifcopenshell.ifcopenshell_wrapper.schema_by_name("IFC4")
entity_to_type_map = {}
entity = None
is_in_where_rule = False
with open(filepath) as fp:
line = fp.readline()
while line:
if "ENTITY " in line:
entity = line[len("ENTITY ") : -1]
elif "END_ENTITY" in line:
is_in_where_rule = False
elif entity and "CorrectTypeAssigned" in line:
is_in_where_rule = True
elif entity and is_in_where_rule and "IN TYPEOF" in line and "RelatingType" in line:
type_class = line.split("'")[1].split(".")[1]
entity_to_type_map.setdefault(entity, []).append(type_class)
line = fp.readline()
# This type of hacky express parsing doesn't accomodate subtypes, so...
def get_inherited_map(declaration):
if not ifcopenshell.util.schema.is_a(declaration, "IfcObject"):
return
if declaration.supertype().name() in entity_to_type_map:
return entity_to_type_map[declaration.supertype().name()]
return get_inherited_map(declaration.supertype())
for declaration in schema4.declarations():
if not hasattr(declaration, "supertype"):
continue
if not ifcopenshell.util.schema.is_a(declaration, "IfcObject"):
continue
if declaration.is_abstract():
continue
if declaration.name() in entity_to_type_map:
continue
inherited_map = get_inherited_map(declaration)
if inherited_map:
entity_to_type_map[declaration.name()] = inherited_map
type_to_entity_map = {value: [key] for key in entity_to_type_map for value in entity_to_type_map[key]}
# IFC2X3 doesn't seem to define this in EXPRESS, so let's just guess
entity_to_type_map2x3 = {}
def guess_type_declaration(declaration):
if not ifcopenshell.util.schema.is_a(declaration, "IfcObject"):
return
try:
type_declaration = schema2x3.declaration_by_name(declaration.name() + "Type")
return type_declaration
except:
pass
try:
type_declaration = schema2x3.declaration_by_name(declaration.name() + "Style")
return type_declaration
except:
pass
return guess_type_declaration(declaration.supertype())
for declaration in schema2x3.declarations():
if not hasattr(declaration, "supertype"):
continue
type_declaration = guess_type_declaration(declaration)
if not type_declaration:
continue
if not type_declaration.is_abstract():
entity_to_type_map2x3.setdefault(declaration.name(), []).append(type_declaration.name())
for subtype in type_declaration.subtypes():
if not subtype.is_abstract():
entity_to_type_map2x3.setdefault(declaration.name(), []).append(subtype.name())
type_to_entity_map2x3 = {value: [key] for key in entity_to_type_map2x3 for value in entity_to_type_map2x3[key]}
with open("entity_to_type_map_4.json", "w") as f:
json.dump(entity_to_type_map, f, indent=4)
with open("entity_to_type_map_2x3.json", "w") as f:
json.dump(entity_to_type_map2x3, f, indent=4)
@@ -0,0 +1,424 @@
{
"IfcBeam": [
"IfcBeamType"
],
"IfcBuilding": [
"IfcSpaceType"
],
"IfcBuildingElement": [
"IfcBeamType",
"IfcBuildingElementProxyType",
"IfcColumnType",
"IfcCoveringType",
"IfcCurtainWallType",
"IfcMemberType",
"IfcPlateType",
"IfcRailingType",
"IfcRampFlightType",
"IfcSlabType",
"IfcStairFlightType",
"IfcWallType"
],
"IfcBuildingElementComponent": [
"IfcBeamType",
"IfcBuildingElementProxyType",
"IfcColumnType",
"IfcCoveringType",
"IfcCurtainWallType",
"IfcMemberType",
"IfcPlateType",
"IfcRailingType",
"IfcRampFlightType",
"IfcSlabType",
"IfcStairFlightType",
"IfcWallType"
],
"IfcBuildingElementPart": [
"IfcBeamType",
"IfcBuildingElementProxyType",
"IfcColumnType",
"IfcCoveringType",
"IfcCurtainWallType",
"IfcMemberType",
"IfcPlateType",
"IfcRailingType",
"IfcRampFlightType",
"IfcSlabType",
"IfcStairFlightType",
"IfcWallType"
],
"IfcBuildingElementProxy": [
"IfcBuildingElementProxyType"
],
"IfcBuildingStorey": [
"IfcSpaceType"
],
"IfcChamferEdgeFeature": [
"IfcDistributionElementType",
"IfcFurnishingElementType",
"IfcTransportElementType"
],
"IfcColumn": [
"IfcColumnType"
],
"IfcCovering": [
"IfcCoveringType"
],
"IfcCurtainWall": [
"IfcCurtainWallType"
],
"IfcDiscreteAccessory": [
"IfcDiscreteAccessoryType",
"IfcVibrationIsolatorType"
],
"IfcDistributionChamberElement": [
"IfcDistributionChamberElementType"
],
"IfcDistributionControlElement": [
"IfcActuatorType",
"IfcAlarmType",
"IfcControllerType",
"IfcFlowInstrumentType",
"IfcSensorType"
],
"IfcDistributionElement": [
"IfcDistributionElementType"
],
"IfcDistributionFlowElement": [
"IfcDistributionChamberElementType"
],
"IfcDoor": [
"IfcDoorStyle"
],
"IfcEdgeFeature": [
"IfcDistributionElementType",
"IfcFurnishingElementType",
"IfcTransportElementType"
],
"IfcElectricalElement": [
"IfcDistributionElementType",
"IfcFurnishingElementType",
"IfcTransportElementType"
],
"IfcElectricDistributionPoint": [
"IfcAirTerminalBoxType",
"IfcDamperType",
"IfcElectricTimeControlType",
"IfcFlowMeterType",
"IfcProtectiveDeviceType",
"IfcSwitchingDeviceType",
"IfcValveType"
],
"IfcElement": [
"IfcDistributionElementType",
"IfcFurnishingElementType",
"IfcTransportElementType"
],
"IfcElementAssembly": [
"IfcDistributionElementType",
"IfcFurnishingElementType",
"IfcTransportElementType"
],
"IfcElementComponent": [
"IfcDiscreteAccessoryType",
"IfcFastenerType"
],
"IfcEnergyConversionDevice": [
"IfcAirToAirHeatRecoveryType",
"IfcBoilerType",
"IfcChillerType",
"IfcCoilType",
"IfcCondenserType",
"IfcCooledBeamType",
"IfcCoolingTowerType",
"IfcElectricGeneratorType",
"IfcElectricMotorType",
"IfcEvaporativeCoolerType",
"IfcEvaporatorType",
"IfcHeatExchangerType",
"IfcHumidifierType",
"IfcMotorConnectionType",
"IfcSpaceHeaterType",
"IfcTransformerType",
"IfcTubeBundleType",
"IfcUnitaryEquipmentType"
],
"IfcEquipmentElement": [
"IfcDistributionElementType",
"IfcFurnishingElementType",
"IfcTransportElementType"
],
"IfcFastener": [
"IfcFastenerType",
"IfcMechanicalFastenerType"
],
"IfcFeatureElement": [
"IfcDistributionElementType",
"IfcFurnishingElementType",
"IfcTransportElementType"
],
"IfcFeatureElementAddition": [
"IfcDistributionElementType",
"IfcFurnishingElementType",
"IfcTransportElementType"
],
"IfcFeatureElementSubtraction": [
"IfcDistributionElementType",
"IfcFurnishingElementType",
"IfcTransportElementType"
],
"IfcFlowController": [
"IfcAirTerminalBoxType",
"IfcDamperType",
"IfcElectricTimeControlType",
"IfcFlowMeterType",
"IfcProtectiveDeviceType",
"IfcSwitchingDeviceType",
"IfcValveType"
],
"IfcFlowFitting": [
"IfcCableCarrierFittingType",
"IfcDuctFittingType",
"IfcJunctionBoxType",
"IfcPipeFittingType"
],
"IfcFlowMovingDevice": [
"IfcCompressorType",
"IfcFanType",
"IfcPumpType"
],
"IfcFlowSegment": [
"IfcCableCarrierSegmentType",
"IfcCableSegmentType",
"IfcDuctSegmentType",
"IfcPipeSegmentType"
],
"IfcFlowStorageDevice": [
"IfcElectricFlowStorageDeviceType",
"IfcTankType"
],
"IfcFlowTerminal": [
"IfcAirTerminalType",
"IfcElectricApplianceType",
"IfcElectricHeaterType",
"IfcFireSuppressionTerminalType",
"IfcGasTerminalType",
"IfcLampType",
"IfcLightFixtureType",
"IfcOutletType",
"IfcSanitaryTerminalType",
"IfcStackTerminalType",
"IfcWasteTerminalType"
],
"IfcFlowTreatmentDevice": [
"IfcDuctSilencerType",
"IfcFilterType"
],
"IfcFooting": [
"IfcBeamType",
"IfcBuildingElementProxyType",
"IfcColumnType",
"IfcCoveringType",
"IfcCurtainWallType",
"IfcMemberType",
"IfcPlateType",
"IfcRailingType",
"IfcRampFlightType",
"IfcSlabType",
"IfcStairFlightType",
"IfcWallType"
],
"IfcFurnishingElement": [
"IfcFurnishingElementType",
"IfcFurnitureType",
"IfcSystemFurnitureElementType"
],
"IfcMechanicalFastener": [
"IfcMechanicalFastenerType"
],
"IfcMember": [
"IfcMemberType"
],
"IfcOpeningElement": [
"IfcDistributionElementType",
"IfcFurnishingElementType",
"IfcTransportElementType"
],
"IfcPile": [
"IfcBeamType",
"IfcBuildingElementProxyType",
"IfcColumnType",
"IfcCoveringType",
"IfcCurtainWallType",
"IfcMemberType",
"IfcPlateType",
"IfcRailingType",
"IfcRampFlightType",
"IfcSlabType",
"IfcStairFlightType",
"IfcWallType"
],
"IfcPlate": [
"IfcPlateType"
],
"IfcProjectionElement": [
"IfcDistributionElementType",
"IfcFurnishingElementType",
"IfcTransportElementType"
],
"IfcRailing": [
"IfcRailingType"
],
"IfcRamp": [
"IfcBeamType",
"IfcBuildingElementProxyType",
"IfcColumnType",
"IfcCoveringType",
"IfcCurtainWallType",
"IfcMemberType",
"IfcPlateType",
"IfcRailingType",
"IfcRampFlightType",
"IfcSlabType",
"IfcStairFlightType",
"IfcWallType"
],
"IfcRampFlight": [
"IfcRampFlightType"
],
"IfcReinforcingBar": [
"IfcBeamType",
"IfcBuildingElementProxyType",
"IfcColumnType",
"IfcCoveringType",
"IfcCurtainWallType",
"IfcMemberType",
"IfcPlateType",
"IfcRailingType",
"IfcRampFlightType",
"IfcSlabType",
"IfcStairFlightType",
"IfcWallType"
],
"IfcReinforcingElement": [
"IfcBeamType",
"IfcBuildingElementProxyType",
"IfcColumnType",
"IfcCoveringType",
"IfcCurtainWallType",
"IfcMemberType",
"IfcPlateType",
"IfcRailingType",
"IfcRampFlightType",
"IfcSlabType",
"IfcStairFlightType",
"IfcWallType"
],
"IfcReinforcingMesh": [
"IfcBeamType",
"IfcBuildingElementProxyType",
"IfcColumnType",
"IfcCoveringType",
"IfcCurtainWallType",
"IfcMemberType",
"IfcPlateType",
"IfcRailingType",
"IfcRampFlightType",
"IfcSlabType",
"IfcStairFlightType",
"IfcWallType"
],
"IfcRoof": [
"IfcBeamType",
"IfcBuildingElementProxyType",
"IfcColumnType",
"IfcCoveringType",
"IfcCurtainWallType",
"IfcMemberType",
"IfcPlateType",
"IfcRailingType",
"IfcRampFlightType",
"IfcSlabType",
"IfcStairFlightType",
"IfcWallType"
],
"IfcRoundedEdgeFeature": [
"IfcDistributionElementType",
"IfcFurnishingElementType",
"IfcTransportElementType"
],
"IfcSite": [
"IfcSpaceType"
],
"IfcSlab": [
"IfcSlabType"
],
"IfcSpace": [
"IfcSpaceType"
],
"IfcSpatialStructureElement": [
"IfcSpaceType"
],
"IfcStair": [
"IfcBeamType",
"IfcBuildingElementProxyType",
"IfcColumnType",
"IfcCoveringType",
"IfcCurtainWallType",
"IfcMemberType",
"IfcPlateType",
"IfcRailingType",
"IfcRampFlightType",
"IfcSlabType",
"IfcStairFlightType",
"IfcWallType"
],
"IfcStairFlight": [
"IfcStairFlightType"
],
"IfcTendon": [
"IfcBeamType",
"IfcBuildingElementProxyType",
"IfcColumnType",
"IfcCoveringType",
"IfcCurtainWallType",
"IfcMemberType",
"IfcPlateType",
"IfcRailingType",
"IfcRampFlightType",
"IfcSlabType",
"IfcStairFlightType",
"IfcWallType"
],
"IfcTendonAnchor": [
"IfcBeamType",
"IfcBuildingElementProxyType",
"IfcColumnType",
"IfcCoveringType",
"IfcCurtainWallType",
"IfcMemberType",
"IfcPlateType",
"IfcRailingType",
"IfcRampFlightType",
"IfcSlabType",
"IfcStairFlightType",
"IfcWallType"
],
"IfcTransportElement": [
"IfcTransportElementType"
],
"IfcVirtualElement": [
"IfcDistributionElementType",
"IfcFurnishingElementType",
"IfcTransportElementType"
],
"IfcWall": [
"IfcWallType"
],
"IfcWallStandardCase": [
"IfcWallType"
],
"IfcWindow": [
"IfcWindowStyle"
]
}
@@ -0,0 +1,329 @@
{
"IfcActuator": [
"IFCACTUATORTYPE"
],
"IfcAirTerminal": [
"IFCAIRTERMINALTYPE"
],
"IfcAirTerminalBox": [
"IFCAIRTERMINALBOXTYPE"
],
"IfcAirToAirHeatRecovery": [
"IFCAIRTOAIRHEATRECOVERYTYPE"
],
"IfcAlarm": [
"IFCALARMTYPE"
],
"IfcAudioVisualAppliance": [
"IFCAUDIOVISUALAPPLIANCETYPE"
],
"IfcBeam": [
"IFCBEAMTYPE"
],
"IfcBoiler": [
"IFCBOILERTYPE"
],
"IfcBuildingElementPart": [
"IFCBUILDINGELEMENTPARTTYPE"
],
"IfcBuildingElementProxy": [
"IFCBUILDINGELEMENTPROXYTYPE"
],
"IfcBurner": [
"IFCBURNERTYPE"
],
"IfcCableCarrierFitting": [
"IFCCABLECARRIERFITTINGTYPE"
],
"IfcCableCarrierSegment": [
"IFCCABLECARRIERSEGMENTTYPE"
],
"IfcCableFitting": [
"IFCCABLEFITTINGTYPE"
],
"IfcCableSegment": [
"IFCCABLESEGMENTTYPE"
],
"IfcChiller": [
"IFCCHILLERTYPE"
],
"IfcChimney": [
"IFCCHIMNEYTYPE"
],
"IfcCoil": [
"IFCCOILTYPE"
],
"IfcColumn": [
"IFCCOLUMNTYPE"
],
"IfcCommunicationsAppliance": [
"IFCCOMMUNICATIONSAPPLIANCETYPE"
],
"IfcCompressor": [
"IFCCOMPRESSORTYPE"
],
"IfcCondenser": [
"IFCCONDENSERTYPE"
],
"IfcController": [
"IFCCONTROLLERTYPE"
],
"IfcCooledBeam": [
"IFCCOOLEDBEAMTYPE"
],
"IfcCoolingTower": [
"IFCCOOLINGTOWERTYPE"
],
"IfcCovering": [
"IFCCOVERINGTYPE"
],
"IfcCurtainWall": [
"IFCCURTAINWALLTYPE"
],
"IfcDamper": [
"IFCDAMPERTYPE"
],
"IfcDiscreteAccessory": [
"IFCDISCRETEACCESSORYTYPE"
],
"IfcDistributionChamberElement": [
"IFCDISTRIBUTIONCHAMBERELEMENTTYPE"
],
"IfcDuctFitting": [
"IFCDUCTFITTINGTYPE"
],
"IfcDuctSegment": [
"IFCDUCTSEGMENTTYPE"
],
"IfcDuctSilencer": [
"IFCDUCTSILENCERTYPE"
],
"IfcElectricAppliance": [
"IFCELECTRICAPPLIANCETYPE"
],
"IfcElectricDistributionBoard": [
"IFCELECTRICDISTRIBUTIONBOARDTYPE"
],
"IfcElectricFlowStorageDevice": [
"IFCELECTRICFLOWSTORAGEDEVICETYPE"
],
"IfcElectricGenerator": [
"IFCELECTRICGENERATORTYPE"
],
"IfcElectricMotor": [
"IFCELECTRICMOTORTYPE"
],
"IfcElectricTimeControl": [
"IFCELECTRICTIMECONTROLTYPE"
],
"IfcElementAssembly": [
"IFCELEMENTASSEMBLYTYPE"
],
"IfcEngine": [
"IFCENGINETYPE"
],
"IfcEvaporativeCooler": [
"IFCEVAPORATIVECOOLERTYPE"
],
"IfcEvaporator": [
"IFCEVAPORATORTYPE"
],
"IfcFan": [
"IFCFANTYPE"
],
"IfcFastener": [
"IFCFASTENERTYPE"
],
"IfcFilter": [
"IFCFILTERTYPE"
],
"IfcFireSuppressionTerminal": [
"IFCFIRESUPPRESSIONTERMINALTYPE"
],
"IfcFlowInstrument": [
"IFCFLOWINSTRUMENTTYPE"
],
"IfcFlowMeter": [
"IFCFLOWMETERTYPE"
],
"IfcFooting": [
"IFCFOOTINGTYPE"
],
"IfcFurniture": [
"IFCFURNITURETYPE"
],
"IfcGeographicElement": [
"IFCGEOGRAPHICELEMENTTYPE"
],
"IfcHeatExchanger": [
"IFCHEATEXCHANGERTYPE"
],
"IfcHumidifier": [
"IFCHUMIDIFIERTYPE"
],
"IfcInterceptor": [
"IFCINTERCEPTORTYPE"
],
"IfcJunctionBox": [
"IFCJUNCTIONBOXTYPE"
],
"IfcLamp": [
"IFCLAMPTYPE"
],
"IfcLightFixture": [
"IFCLIGHTFIXTURETYPE"
],
"IfcMechanicalFastener": [
"IFCMECHANICALFASTENERTYPE"
],
"IfcMedicalDevice": [
"IFCMEDICALDEVICETYPE"
],
"IfcMember": [
"IFCMEMBERTYPE"
],
"IfcMotorConnection": [
"IFCMOTORCONNECTIONTYPE"
],
"IfcOutlet": [
"IFCOUTLETTYPE"
],
"IfcPile": [
"IFCPILETYPE"
],
"IfcPipeFitting": [
"IFCPIPEFITTINGTYPE"
],
"IfcPipeSegment": [
"IFCPIPESEGMENTTYPE"
],
"IfcPlate": [
"IFCPLATETYPE"
],
"IfcProtectiveDevice": [
"IFCPROTECTIVEDEVICETYPE"
],
"IfcProtectiveDeviceTrippingUnit": [
"IFCPROTECTIVEDEVICETRIPPINGUNITTYPE"
],
"IfcPump": [
"IFCPUMPTYPE"
],
"IfcRailing": [
"IFCRAILINGTYPE"
],
"IfcRamp": [
"IFCRAMPTYPE"
],
"IfcRampFlight": [
"IFCRAMPFLIGHTTYPE"
],
"IfcReinforcingBar": [
"IFCREINFORCINGBARTYPE"
],
"IfcReinforcingMesh": [
"IFCREINFORCINGMESHTYPE"
],
"IfcRoof": [
"IFCROOFTYPE"
],
"IfcSanitaryTerminal": [
"IFCSANITARYTERMINALTYPE"
],
"IfcSensor": [
"IFCSENSORTYPE"
],
"IfcShadingDevice": [
"IFCSHADINGDEVICETYPE"
],
"IfcSlab": [
"IFCSLABTYPE"
],
"IfcSolarDevice": [
"IFCSOLARDEVICETYPE"
],
"IfcSpace": [
"IFCSPACETYPE"
],
"IfcSpaceHeater": [
"IFCSPACEHEATERTYPE"
],
"IfcSpatialZone": [
"IFCSPATIALZONETYPE"
],
"IfcStackTerminal": [
"IFCSTACKTERMINALTYPE"
],
"IfcStair": [
"IFCSTAIRTYPE"
],
"IfcStairFlight": [
"IFCSTAIRFLIGHTTYPE"
],
"IfcSwitchingDevice": [
"IFCSWITCHINGDEVICETYPE"
],
"IfcSystemFurnitureElement": [
"IFCSYSTEMFURNITUREELEMENTTYPE"
],
"IfcTank": [
"IFCTANKTYPE"
],
"IfcTendon": [
"IFCTENDONTYPE"
],
"IfcTendonAnchor": [
"IFCTENDONANCHORTYPE"
],
"IfcTransformer": [
"IFCTRANFORMERTYPE"
],
"IfcTransportElement": [
"IFCTRANSPORTELEMENTTYPE"
],
"IfcTubeBundle": [
"IFCTUBEBUNDLETYPE"
],
"IfcUnitaryControlElement": [
"IFCUNITARYCONTROLELEMENTTYPE"
],
"IfcUnitaryEquipment": [
"IFCUNITARYEQUIPMENTTYPE"
],
"IfcValve": [
"IFCVALVETYPE"
],
"IfcVibrationIsolator": [
"IFCVIBRATIONISOLATORTYPE"
],
"IfcWall": [
"IFCWALLTYPE"
],
"IfcWasteTerminal": [
"IFCWASTETERMINALTYPE"
],
"IfcBeamStandardCase": [
"IFCBEAMTYPE"
],
"IfcColumnStandardCase": [
"IFCCOLUMNTYPE"
],
"IfcMemberStandardCase": [
"IFCMEMBERTYPE"
],
"IfcPlateStandardCase": [
"IFCPLATETYPE"
],
"IfcSlabElementedCase": [
"IFCSLABTYPE"
],
"IfcSlabStandardCase": [
"IFCSLABTYPE"
],
"IfcWallElementedCase": [
"IFCWALLTYPE"
],
"IfcWallStandardCase": [
"IFCWALLTYPE"
]
}
@@ -0,0 +1,29 @@
import os
import json
cwd = os.path.dirname(os.path.realpath(__file__))
entity_to_type_map = {}
type_to_entity_map = {}
with open(os.path.join(cwd, "entity_to_type_map_2x3.json")) as f:
entity_to_type_map["IFC2X3"] = json.load(f)
with open(os.path.join(cwd, "entity_to_type_map_4.json")) as f:
entity_to_type_map["IFC4"] = json.load(f)
type_to_entity_map["IFC2X3"] = {
value: [key] for key in entity_to_type_map["IFC2X3"] for value in entity_to_type_map["IFC2X3"][key]
}
type_to_entity_map["IFC4"] = {
value: [key] for key in entity_to_type_map["IFC4"] for value in entity_to_type_map["IFC4"][key]
}
def get_applicable_types(ifc_class, schema="IFC4"):
return entity_to_type_map[schema].get(ifc_class, [])
def get_applicable_entities(ifc_type_class, schema="IFC4"):
return type_to_entity_map[schema].get(ifc_type_class, [])