Files
IfcOpenShell/src/ifctester/webapp/public/worker/api.py
T
Andrej730 be66d4884d typing
2025-09-15 18:27:19 +05:00

196 lines
7.2 KiB
Python

import ifcopenshell
import ifcopenshell.util
import ifcopenshell.util.attribute
import ifcopenshell.util.pset
import ifcopenshell.util.schema
import xml.etree.ElementTree as ET
from xmlschema.validators.exceptions import XMLSchemaValidationError
from ifctester.ids import Ids, IdsXmlValidationError, get_schema
# https://github.com/buildingSMART/IDS/blob/9914d568c7ac037acd97e58a0d16e9f93c3e3416/Schema/ids.xsd#L232
ifc_schemas = ["IFC2X3", "IFC4", "IFC4X3_ADD2"]
def get_predefined_types_for_entity(schema_name, entity_name):
"""Get a list of predefined types for a given entity."""
schema = ifcopenshell.schema_by_name(schema_name)
try:
entity = schema.declaration_by_name(entity_name)
except:
return []
if not entity or not entity.as_entity():
print(f"Entity {entity_name} not found")
return []
entity = entity.as_entity()
predefined_type_attr = None
# Check all attributes for "PredefinedType"
for attr in entity.all_attributes():
if attr.name() == "PredefinedType":
predefined_type_attr = attr
break
if not predefined_type_attr:
return []
param_type = predefined_type_attr.type_of_attribute()
if param_type.as_named_type():
enum_decl = param_type.as_named_type().declared_type()
if enum_decl.as_enumeration_type():
return enum_decl.as_enumeration_type().enumeration_items()
return []
def get_all_entity_classes(schema_name):
"""Get all IFC entity classes in the given schema."""
schema = ifcopenshell.schema_by_name(schema_name)
entities = []
for entity in schema.entities():
entities.append(entity.name())
# Sort alphabetically
entities.sort()
return entities
def get_all_data_types(schema_name):
"""Get all data types in the given schema."""
schema = ifcopenshell.schema_by_name(schema_name)
return {
d.name(): ifcopenshell.util.attribute.get_primitive_type(d)
for d in schema.declarations()
if d.as_type_declaration()
}
def get_entity_attributes(schema_name, entity_name):
"""Get all attributes for a given entity."""
schema = ifcopenshell.schema_by_name(schema_name)
try:
entity = schema.declaration_by_name(entity_name)
except:
return []
if not entity or not entity.as_entity():
print(f"Entity {entity_name} not found")
return []
entity = entity.as_entity()
attributes = []
for attr in entity.all_attributes():
attributes.append(
{
"name": attr.name(),
# "type": attr.type_of_attribute() # TODO Types of attribute
}
)
return attributes
def get_applicable_psets(schema_name, entity_name, predefined_type=""):
"""Get all applicable property and quantity sets for a given entity."""
pset_qto = ifcopenshell.util.pset.PsetQto(schema_name)
pset_names = pset_qto.get_applicable_names(entity_name, predefined_type)
return pset_names
def get_all_psets(schema_name):
"""Get all property sets and quantity sets defined in an IFC schema"""
pset_qto = ifcopenshell.util.pset.PsetQto(schema_name)
result = {}
for template_file in pset_qto.templates:
for pset_template in template_file.by_type("IfcPropertySetTemplate"):
pset_name = pset_template.Name
properties = []
# Get property templates for this pset
if pset_template.HasPropertyTemplates:
for prop_template in pset_template.HasPropertyTemplates:
prop_info = {
"name": prop_template.Name,
# "description": prop_template.Description
}
# Extract type information
if prop_template.is_a("IfcSimplePropertyTemplate"):
if prop_template.PrimaryMeasureType:
prop_info["type"] = prop_template.PrimaryMeasureType
else:
prop_info["type"] = str(prop_template.TemplateType)
elif prop_template.is_a("IfcComplexPropertyTemplate"):
prop_info["type"] = None # Complex properties are not supported
else:
prop_info["type"] = None
properties.append(prop_info)
result[pset_name] = properties
return result
def get_material_categories():
return ["concrete", "steel", "aluminium", "block", "brick", "stone", "wood", "glass", "gypsum", "plastic", "earth"]
def get_standard_classification_systems():
return {
"BB/SfB (3/4 cijfers)": {"source": "Regie der Gebouwen", "tokens": ["."]},
"BIMTypeCode": {"source": "BIMStockholm", "tokens": None},
"Common Arrangement of Work Sections (CAWS)": {"source": "NBS", "tokens": ["/"]},
"CBI Classification - Level 2": {"source": "Masterspec", "tokens": None},
"CBI Classification - Level 4": {"source": "Masterspec", "tokens": None},
"Rumsfunktionskoder CC001 - 001": {"source": "BIMAlliance", "tokens": ["-"]},
"CCS": {"source": "Molio", "tokens": None},
"CCTB": {"source": "CCT-Bâtiments", "tokens": ["."]},
"Funktionskoder Regionservice CD001 - 001": {"source": "BIMAlliance", "tokens": None},
"Rumsfunktion Blekinge CD002 - 001": {"source": "BIMAlliance", "tokens": None},
"EcoQuaestor Codetabel": {"source": "EcoQuaestor", "tokens": [".", "-"]},
"GuBIMclass CA": {"source": "GuBIMClass", "tokens": ["."]},
"GuBIMclass ES": {"source": "GuBIMClass", "tokens": ["."]},
"MasterFormat": {"source": "CSI", "tokens": [" ", "."]},
"NATSPEC Worksections": {"source": "NATSPEC", "tokens": None},
"NBS Create": {"source": "NBS", "tokens": ["_", "/"]},
"NL/SfB (4 cijfers)": {"source": "BIMLoket", "tokens": ["."]},
"NS 3451 - Bygningsdelstabell": {"source": "Standard Norge", "tokens": None},
"OmniClass": {"source": "OmniClass", "tokens": ["-", " "]},
"ÖNORM 6241-2": {"source": "freeBIM 2", "tokens": None},
"RICS NRM1": {"source": "RICS", "tokens": ["."]},
"RICS NRM3": {"source": "RICS", "tokens": ["."]},
"SFG20": {"source": "SFG20", "tokens": ["-"]},
"SINAPI": {"source": "Caixa", "tokens": ["/"]},
"STABU-Element": {"source": "STABU", "tokens": ["."]},
"TALO 2000 Building Component Classification": {"source": "Rakennustieto", "tokens": ["."]},
"TALO 2000 Hankenimikkeistö": {"source": "Rakennustieto", "tokens": ["."]},
"Uniclass": {"source": "RIBA Enterprises Ltd", "tokens": ["_"]},
"Uniclass 2015": {"source": "RIBA Enterprises Ltd", "tokens": ["_"]},
"UniFormat": {"source": "UniFormat", "tokens": ["."]},
"Uniformat": {"source": "UniFormat", "tokens": ["."]},
"VMSW": {"source": "VMSW", "tokens": ["."]},
}
def ids_from_xml_string(xml: str, validate: bool = False) -> Ids:
try:
decode = get_schema().decode(
xml, strip_namespaces=True, namespaces={"": "http://standards.buildingsmart.org/IDS"}
)
except XMLSchemaValidationError as e:
raise IdsXmlValidationError(e, "Provided XML appears to be invalid. See details above.")
return Ids().parse(decode)