Coverage for bim2sim/tasks/common/create_relations.py: 18%
39 statements
« prev ^ index » next coverage.py v7.6.12, created at 2025-03-12 17:09 +0000
« prev ^ index » next coverage.py v7.6.12, created at 2025-03-12 17:09 +0000
1from bim2sim.elements.base_elements import IFCBased
2from bim2sim.elements.bps_elements import (
3 ThermalZone, Storey, Building, ExternalSpatialElement)
4from bim2sim.tasks.base import ITask
5from bim2sim.elements.mapping.ifc2python import getBuilding, getStorey, getSite
8class CreateRelations(ITask):
9 """Relations of elements, run() method holds detailed information."""
10 reads = ('elements',)
12 def run(self, elements: dict[str, IFCBased]):
13 """Bind ThermalZone to ProductBased/Storey/Building and vice versa.
15 This is needed as our CreateElements task does not work hierarchic. So
16 we need to create the relations after initial creation.
17 Problem: Following IFC-schema rules a space that is stretched over
18 multiple storeys should only be assigned to one of these storeys. From
19 IFC-Schema:
20 "NOTE: Multi storey spaces shall be spatially contained by only a
21 single building storey, usually it is the building storey where the
22 base of the space lies.
23 TODO: this might me solved via PyOCCTools.obj2_in_obj1 but this needs
24 all shapes to be existing for ThermalZone instances and Storeys
25 "
27 Args:
28 elements: dict[guid: element]
29 """
30 self.logger.info("Creating bim2sim elements relations.")
31 for element in elements.values():
32 # connect element to site and vice versa
33 ifc_site = getSite(element.ifc)
34 if ifc_site:
35 element_site = elements.get(
36 ifc_site.GlobalId, None)
37 if isinstance(element, Building):
38 if element not in element_site.buildings:
39 element_site.buildings.append(element)
41 # connect element to building and vice versa
42 ifc_building = getBuilding(element.ifc)
43 if ifc_building:
44 element_building = elements.get(
45 ifc_building.GlobalId, None)
46 if isinstance(element, Storey):
47 if element not in element_building.storeys:
48 element_building.storeys.append(element)
49 if isinstance(element, ThermalZone):
50 if not isinstance(element, ExternalSpatialElement):
51 if element not in element_building.thermal_zones:
52 element_building.thermal_zones.append(element)
53 else:
54 if element not in element_building.elements:
55 element_building.elements.append(element)
56 element.building = element_building
58 # connect element to storey and vice versa
59 ifc_storey = getStorey(element.ifc)
60 if ifc_storey:
61 element_storey = elements.get(
62 ifc_storey.GlobalId, None)
63 if isinstance(element, ThermalZone):
64 if not isinstance(element, ExternalSpatialElement):
65 if element not in element_storey.thermal_zones:
66 element_storey.thermal_zones.append(element)
67 else:
68 if element not in element_storey.elements:
69 element_storey.elements.append(element)
70 if element not in element.storeys:
71 element.storeys.append(element_storey)
72 # relations between element and space are handled in sb_creation
73 # as more robust