ifcbim

How to fetch hierachical spatial structure and contained products from an IFC model?


I am currently working on a project to fetch all the details like IfcBuilding, IfcDistributionControlElement etc. from an IFC file stored in Opensource BIMserver. Using the Java client library, I managed to get a list of storeys and print their names.

List<IfcBuildingStorey> storeys = model.getAllWithSubTypes(IfcBuildingStorey.class));
for (IfcBuildingStorey storey : storeys) {
    System.out.println(storey.getName());
}

Current Output:

Level 1
Level 2
Level 3
Level 4

What i want is for each storey, e.g. Level 2, to get all the rooms located in that storey, and then all entities of type IfcProduct, e.g. fire detectors, inside those rooms in a hierarchical way.

Expected Output:

Level 2
  Room 1: entity 1, entity 2, entity 3, entity 4
  Room 2: entity 1, entity 2, entity 3, entity 4
  Room 3: entity 1, entity 2, entity 3, entity 4

Solution

  • Starting from the list of IfcBuildingStorey entities you would have to work your way through the spatial hierarchy as described in the IFC Documentation. Be aware that you do not necessarily have a simple two-level structure of IfcBuildingStorey and IfcSpace, but the aggregation tree may contain up to three hierarchy levels of storeys as well as of spaces:

    1. groups of storey/space (compositiontype COMPLEX) composed of
    2. storey/space elements (compositionType ELEMENT) composed of
    3. storey/space parts (compositionType PARTIAL).

    You reach the respective next lower level via the objectified aggregation relationship:

    Then hope that the IfcObjectDefinition instance is a spatial structure (it should be, but you never know).

    In Java this could look like this:

    void traverseSpatialStructure(IfcSpatialStructureElement parent){
      for (IfcRelAggregates aggregation: parent.getIsDecomposedBy()){
        for (IfcObjectDefinition child: aggregation.getRelatedObjects()){
          doSomeThingWith(child); // e.g. print name
          assert child instanceof IfcSpatialStructureElement;
          traverseSpatialStructure((IfcSpatialStructureElement) child);
        }
      }
    }
    

    Finally, once you reached the IfcSpace level, use the spatial containment relation to get hold of every product contained in the space:

    In Java again:

    void doSomethingWith(IfcSpace spatialStructure){
      for(IfcRelContainedInSpatialStructure containment: spatialstructure.getContainsElements()){
        for(IfcProduct product : containment.getRelatedElements()){
          // do something with your product, e.g. fire detector
        }
      }
    }