187 lines
5.4 KiB
Python
187 lines
5.4 KiB
Python
# IfcOpenShell - IFC toolkit and geometry engine
|
|
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
|
#
|
|
# This file is part of IfcOpenShell.
|
|
#
|
|
# IfcOpenShell is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU Lesser General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# IfcOpenShell is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU Lesser General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU Lesser General Public License
|
|
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
from typing import Literal
|
|
|
|
from typing_extensions import assert_never
|
|
|
|
import ifcopenshell
|
|
import ifcopenshell.ifcopenshell_wrapper as W
|
|
import ifcopenshell.util.attribute
|
|
|
|
# COBie actually uses an exclusion list, but this inclusion list is equivalent.
|
|
cobie_type_classes = [
|
|
"IfcDoorStyle",
|
|
"IfcBuildingElementProxyType",
|
|
"IfcChimneyType",
|
|
"IfcCoveringType",
|
|
"IfcDoorType",
|
|
"IfcFootingType",
|
|
"IfcPileType",
|
|
"IfcRoofType",
|
|
"IfcShadingDeviceType",
|
|
"IfcWindowType",
|
|
"IfcDistributionControlElementType",
|
|
"IfcDistributionChamberElementType",
|
|
"IfcEnergyConversionDeviceType",
|
|
"IfcFlowControllerType",
|
|
"IfcFlowMovingDeviceType",
|
|
"IfcFlowStorageDeviceType",
|
|
"IfcFlowTerminalType",
|
|
"IfcFlowTreatmentDeviceType",
|
|
"IfcElementAssemblyType",
|
|
"IfcBuildingElementPartType",
|
|
"IfcDiscreteAccessoryType",
|
|
"IfcMechanicalFastenerType",
|
|
"IfcReinforcingElementType",
|
|
"IfcVibrationIsolatorType",
|
|
"IfcFurnishingElementType",
|
|
"IfcGeographicElementType",
|
|
"IfcTransportElementType",
|
|
"IfcSpatialZoneType",
|
|
"IfcWindowStyle",
|
|
]
|
|
|
|
cobie_component_classes = [
|
|
"IfcBuildingElementProxy",
|
|
"IfcChimney",
|
|
"IfcCovering",
|
|
"IfcDoor",
|
|
"IfcShadingDevice",
|
|
"IfcWindow",
|
|
"IfcDistributionControlElement",
|
|
"IfcDistributionChamberElement",
|
|
"IfcEnergyConversionDevice",
|
|
"IfcFlowController",
|
|
"IfcFlowMovingDevice",
|
|
"IfcFlowStorageDevice",
|
|
"IfcFlowTerminal",
|
|
"IfcFlowTreatmentDevice",
|
|
"IfcDiscreteAccessory",
|
|
"IfcTendon",
|
|
"IfcTendonAnchor",
|
|
"IfcVibrationIsolator",
|
|
"IfcFurnishingElement",
|
|
"IfcGeographicElement",
|
|
"IfcTransportElement",
|
|
]
|
|
|
|
fmhem_classes_ifc4 = [
|
|
"IfcDoorType",
|
|
"IfcWindowType",
|
|
"IfcShadingDeviceType",
|
|
"IfcDistributionControlElementType",
|
|
"IfcEnergyConversionDeviceType",
|
|
"IfcFlowControllerType",
|
|
"IfcFlowMovingDeviceType",
|
|
"IfcFlowStorageDeviceType",
|
|
"IfcFlowTerminalType",
|
|
"IfcFlowTreatmentDeviceType",
|
|
"IfcFurnishingElementType",
|
|
"IfcTransportElementType",
|
|
]
|
|
|
|
fmhem_classes_ifc2x3 = [
|
|
"IfcDoorStyle",
|
|
"IfcWindowStyle",
|
|
"IfcShadingDeviceType",
|
|
"IfcDistributionControlElementType",
|
|
"IfcEnergyConversionDeviceType",
|
|
"IfcFlowControllerType",
|
|
"IfcFlowMovingDeviceType",
|
|
"IfcFlowStorageDeviceType",
|
|
"IfcFlowTerminalType",
|
|
"IfcFlowTreatmentDeviceType",
|
|
"IfcFurnishingElementType",
|
|
"IfcTransportElementType",
|
|
]
|
|
|
|
fmhem_excluded_classes = [
|
|
"IfcCooledBeamType",
|
|
"IfcBurnerType",
|
|
"IfcCoilType",
|
|
"IfcLampType",
|
|
]
|
|
|
|
|
|
def get_cobie_types(ifc_file: ifcopenshell.file) -> list[ifcopenshell.entity_instance]:
|
|
elements = []
|
|
for ifc_class in cobie_type_classes:
|
|
try:
|
|
elements += ifc_file.by_type(ifc_class)
|
|
except:
|
|
pass
|
|
return elements
|
|
|
|
|
|
def get_cobie_components(ifc_file: ifcopenshell.file) -> list[ifcopenshell.entity_instance]:
|
|
elements = []
|
|
for ifc_class in cobie_component_classes:
|
|
try:
|
|
elements += ifc_file.by_type(ifc_class)
|
|
except:
|
|
pass
|
|
return elements
|
|
|
|
|
|
def get_fmhem_types(ifc_file: ifcopenshell.file) -> list[ifcopenshell.entity_instance]:
|
|
elements = []
|
|
if ifc_file.schema == "IFC2X3":
|
|
fmhem_classes = fmhem_classes_ifc2x3
|
|
else:
|
|
fmhem_classes = fmhem_classes_ifc4
|
|
for ifc_class in fmhem_classes:
|
|
try:
|
|
elements += [e for e in ifc_file.by_type(ifc_class) if e.is_a() not in fmhem_excluded_classes]
|
|
except:
|
|
pass
|
|
return elements
|
|
|
|
|
|
def get_fmhem_classes(schema: Literal["IFC4", "IFC2X3"] = "IFC4") -> dict[str, list[str]]:
|
|
results = {}
|
|
|
|
def get_fmhem_class(declaration: W.entity) -> None:
|
|
if declaration.name() in fmhem_excluded_classes:
|
|
pass
|
|
elif declaration.is_abstract():
|
|
pass
|
|
else:
|
|
types = []
|
|
for attribute in declaration.all_attributes():
|
|
if attribute.name() == "PredefinedType":
|
|
types = list(ifcopenshell.util.attribute.get_enum_items(attribute))
|
|
if "NOTDEFINED" in types:
|
|
types.remove("NOTDEFINED")
|
|
results[declaration.name()] = types
|
|
|
|
for subtype in declaration.subtypes():
|
|
get_fmhem_class(subtype)
|
|
|
|
if schema == "IFC4":
|
|
classes = fmhem_classes_ifc4
|
|
elif schema == "IFC2X3":
|
|
classes = fmhem_classes_ifc2x3
|
|
else:
|
|
assert_never(schema)
|
|
schema_ = ifcopenshell.schema_by_name(schema)
|
|
for ifc_class in classes:
|
|
declaration = schema_.declaration_by_name(ifc_class)
|
|
get_fmhem_class(declaration)
|
|
return results
|