private void processBuilding(CityModel cityModel, IfcBuilding ifcBuilding)
      throws SerializerException {
    Building building = new Building();
    setGlobalId(building, ifcBuilding);
    setName(building.getName(), ifcBuilding.getName());

    CityObjectMember cityObjectMember = new CityObjectMember();
    cityObjectMember.setCityObject(building);
    cityModel.addCityObjectMember(cityObjectMember);

    IfcPostalAddress ifcBuildingAddress = ifcBuilding.getBuildingAddress();
    if (ifcBuildingAddress != null) {
      building.addAddress(createAddress(ifcBuildingAddress));
    }

    for (IfcRelContainedInSpatialStructure ifcRelContainedInSpatialStructure :
        ifcBuilding.getContainsElements()) {
      for (IfcProduct ifcProduct : ifcRelContainedInSpatialStructure.getRelatedElements()) {
        processBoundary(building, createFakeRoom(building), ifcProduct, null);
      }
    }

    for (IfcRelDecomposes ifcRelDecomposes : ifcBuilding.getIsDecomposedBy()) {
      for (IfcObjectDefinition ifcObjectDefinition : ifcRelDecomposes.getRelatedObjects()) {
        if (ifcObjectDefinition instanceof IfcBuildingStorey) {
          IfcBuildingStorey ifcBuildingStorey = (IfcBuildingStorey) ifcObjectDefinition;
          processStorey(building, ifcBuildingStorey);
        }
      }
    }
  }
 private void processStorey(Building building, IfcBuildingStorey ifcBuildingStorey)
     throws SerializerException {
   for (IfcRelDecomposes ifcRelDecomposes : ifcBuildingStorey.getIsDecomposedBy()) {
     for (IfcObjectDefinition ifcObjectDefinition : ifcRelDecomposes.getRelatedObjects()) {
       if (ifcObjectDefinition instanceof IfcSpace) {
         IfcSpace ifcSpace = (IfcSpace) ifcObjectDefinition;
         processSpace(building, ifcSpace);
       }
     }
   }
   for (IfcRelContainedInSpatialStructure ifcRelContainedInSpatialStructure :
       ifcBuildingStorey.getContainsElements()) {
     for (IfcProduct ifcProduct : ifcRelContainedInSpatialStructure.getRelatedElements()) {
       if (!convertedObjects.containsKey(ifcProduct)) {
         Room room = createFakeRoom(building);
         processBoundary(building, room, ifcProduct, null);
         if (ifcProduct instanceof IfcSpace) {
           IfcSpace ifcSpace = (IfcSpace) ifcProduct;
           processSpace(building, ifcSpace);
         } else if (ifcProduct instanceof IfcSlab) {
           convertSlab(building, room, (IfcSlab) ifcProduct);
         }
       }
     }
   }
   for (IfcRelContainedInSpatialStructure spatialStructure :
       ifcBuildingStorey.getContainsElements()) {
     for (IfcProduct ifcProduct : spatialStructure.getRelatedElements()) {
       if (ifcProduct instanceof IfcRoof) {
         RoofSurface roofSurface = new RoofSurface();
         MultiSurfaceProperty roofMSP = new MultiSurfaceProperty();
         MultiSurface roofMs = new MultiSurface();
         roofMSP.setMultiSurface(roofMs);
         roofSurface.setLod4MultiSurface(roofMSP);
         setGeometry(roofMs, (IfcProduct) ifcProduct);
         BoundarySurfaceProperty boundarySurfaceProperty = new BoundarySurfaceProperty();
         boundarySurfaceProperty.setObject(roofSurface);
         convertedObjects.put(ifcProduct, roofSurface);
         setName(roofSurface.getName(), ifcProduct.getName());
         setGlobalId(roofSurface, ifcProduct);
         // IfcRoof ifcRoof = (IfcRoof) ifcProduct;
         // RoofTypeEnum roofTypeEnum =
         // RoofTypeEnum.valueOf(ifcRoof.getShapeType().getName());
         // roofSurface.addGenericApplicationPropertyOfCityObject(roofTypeEnum);
         building.addBoundedBySurface(boundarySurfaceProperty);
       } else {
         List<Element> processProduct = processProduct(ifcProduct);
         if (processProduct != null) {
           for (Element element : processProduct) {
             building.addGenericADEComponent(new ADEComponent(element));
           }
         }
       }
     }
   }
 }
 private void processSpace(Building building, IfcSpace ifcSpace) throws SerializerException {
   Room room = new Room();
   setName(room.getName(), ifcSpace.getName());
   setGlobalId(room, ifcSpace);
   convertedObjects.put(ifcSpace, room);
   MultiSurfaceProperty multiSurfaceProperty = new MultiSurfaceProperty();
   MultiSurface ms = new MultiSurface();
   multiSurfaceProperty.setMultiSurface(ms);
   room.setLod4MultiSurface(multiSurfaceProperty);
   InteriorRoomProperty createInteriorRoomProperty = new InteriorRoomProperty();
   createInteriorRoomProperty.setObject(room);
   building.addInteriorRoom(createInteriorRoomProperty);
   setGeometry(ms, ifcSpace);
   for (IfcRelSpaceBoundary boundary : ifcSpace.getBoundedBy()) {
     if (!convertedObjects.containsKey(boundary.getRelatedBuildingElement())) {
       processBoundary(
           building,
           room,
           boundary.getRelatedBuildingElement(),
           boundary.getInternalOrExternalBoundary());
     }
   }
   for (IfcRelContainedInSpatialStructure contains : ifcSpace.getContainsElements()) {
     for (IfcProduct ifcProduct : contains.getRelatedElements()) {
       if (!convertedObjects.containsKey(ifcProduct)) {
         processBoundary(building, room, ifcProduct, null);
       }
     }
   }
 }
 private Room createFakeRoom(Building building) {
   Room room = new Room();
   MultiSurfaceProperty multiSurfaceProperty = new MultiSurfaceProperty();
   MultiSurface ms = new MultiSurface();
   multiSurfaceProperty.setMultiSurface(ms);
   room.setLod4MultiSurface(multiSurfaceProperty);
   InteriorRoomProperty createInteriorRoomProperty = new InteriorRoomProperty();
   createInteriorRoomProperty.setObject(room);
   building.addInteriorRoom(createInteriorRoomProperty);
   return room;
 }
 private RoofSurface createRoof(Building building, IfcProduct ifcRelating)
     throws SerializerException {
   RoofSurface roofSurface = new RoofSurface();
   MultiSurfaceProperty roofMSP = new MultiSurfaceProperty();
   MultiSurface roofMs = new MultiSurface();
   roofMSP.setMultiSurface(roofMs);
   roofSurface.setLod4MultiSurface(roofMSP);
   setGeometry(roofMs, ifcRelating);
   BoundarySurfaceProperty boundarySurfaceProperty = new BoundarySurfaceProperty();
   boundarySurfaceProperty.setObject(roofSurface);
   building.addBoundedBySurface(boundarySurfaceProperty);
   setName(roofSurface.getName(), ifcRelating.getName());
   setGlobalId(roofSurface, ifcRelating);
   return roofSurface;
 }
 private void processBoundary(
     Building building, Room room, IfcProduct ifcElement, IfcInternalOrExternalEnum boundayType)
     throws SerializerException {
   if (ifcElement instanceof IfcWall) {
     IfcWall ifcWall = (IfcWall) ifcElement;
     if (!convertedObjects.containsKey(ifcWall)) {
       AbstractBoundarySurface boundarySurface = null;
       if (boundayType == null || boundayType == IfcInternalOrExternalEnum.INTERNAL) {
         boundarySurface = new InteriorWallSurface();
       } else {
         boundarySurface = new WallSurface();
       }
       setName(boundarySurface.getName(), ifcWall.getName());
       setGlobalId(boundarySurface, ifcWall);
       convertedObjects.put(ifcWall, boundarySurface);
       BoundarySurfaceProperty boundarySurfaceProperty = new BoundarySurfaceProperty();
       boundarySurfaceProperty.setObject(boundarySurface);
       MultiSurface wallMs = new MultiSurface();
       MultiSurfaceProperty wallMSP = new MultiSurfaceProperty();
       wallMSP.setMultiSurface(wallMs);
       boundarySurface.setLod4MultiSurface(wallMSP);
       setGeometry(wallMs, ifcWall);
       building.addBoundedBySurface(boundarySurfaceProperty);
       for (IfcRelVoidsElement ifcRelVoidsElement : ifcWall.getHasOpenings()) {
         IfcOpeningElement ifcOpeningElement =
             (IfcOpeningElement) ifcRelVoidsElement.getRelatedOpeningElement();
         for (IfcRelFillsElement filling : ifcOpeningElement.getHasFillings()) {
           IfcElement ifcRelatedBuildingElement = filling.getRelatedBuildingElement();
           if (ifcRelatedBuildingElement instanceof IfcWindow) {
             if (!convertedObjects.containsKey(ifcRelatedBuildingElement)) {
               Window window = createWindow((IfcWindow) ifcRelatedBuildingElement);
               OpeningProperty openingProperty = new OpeningProperty();
               openingProperty.setObject(window);
               boundarySurface.addOpening(openingProperty);
               convertedObjects.put(ifcRelatedBuildingElement, window);
             }
           } else if (ifcRelatedBuildingElement instanceof IfcDoor) {
             if (!convertedObjects.containsKey(ifcRelatedBuildingElement)) {
               Door door = createDoor(ifcRelatedBuildingElement);
               OpeningProperty openingProperty = new OpeningProperty();
               openingProperty.setObject(door);
               boundarySurface.addOpening(openingProperty);
               convertedObjects.put(ifcRelatedBuildingElement, door);
             }
           }
         }
       }
     }
   } else if (ifcElement instanceof IfcSlab) {
     convertSlab(building, room, (IfcSlab) ifcElement);
   } else if (ifcElement instanceof IfcRoof) {
     if (!convertedObjects.containsKey(ifcElement)) {
       RoofSurface roofSurface = createRoof(building, ifcElement);
       convertedObjects.put(ifcElement, roofSurface);
     }
   } else if (ifcElement instanceof IfcOpeningElement) {
     List<Element> processProduct = processProduct(ifcElement);
     if (processProduct != null) {
       for (Element element : processProduct) {
         room.addGenericADEComponent(new ADEComponent(element));
       }
     }
   } else if (ifcElement instanceof IfcColumn) {
     // List<Element> processProduct = processProduct(ifcElement);
     // if (processProduct != null) {
     // room.addGenericApplicationPropertyOfRoom(processProduct);
     // }
   } else if (ifcElement == null
       || ifcElement instanceof IfcWindow
       || ifcElement instanceof IfcDoor
       || ifcElement instanceof IfcVirtualElement) {
     // ignore
   } else if (ifcElement instanceof IfcFurnishingElement) {
     // BuildingFurniture buildingFurniture =
     // citygml.createBuildingFurniture();
     // GeometryProperty createGeometryProperty =
     // gml.createGeometryProperty();
     // MultiSurface createMultiSurface = gml.createMultiSurface();
     // setGeometry(createMultiSurface, ifcElement);
     // createGeometryProperty.setGeometry(createMultiSurface);
     // buildingFurniture.setLod4Geometry(createGeometryProperty);
     // InteriorFurnitureProperty ifp =
     // citygml.createInteriorFurnitureProperty();
     // ifp.setObject(buildingFurniture);
     // setName(buildingFurniture.getName(), ifcElement.getName());
     // setGlobalId(buildingFurniture, ifcElement);
     // room.addInteriorFurniture(ifp);
     // convertedObjects.put(ifcElement, buildingFurniture);
   } else if (ifcElement instanceof IfcFlowTerminal) {
     // FlowTerminal flowTerminal = new FlowTerminal();
     // setName(flowTerminal.getName(), ifcElement.getName());
     // MultiSurfaceProperty createGeometryProperty =
     // gml.createMultiSurfaceProperty();
     // MultiSurface createMultiSurface = gml.createMultiSurface();
     // setGeometry(createMultiSurface, ifcElement);
     // createGeometryProperty.setMultiSurface(createMultiSurface);
     // flowTerminal.setLod4MultiSurface(createGeometryProperty);
     // room.getGenericApplicationPropertyOfRoom().add(flowTerminal);
     // setName(flowTerminal.getName(), ifcElement.getName());
     // setGlobalId(flowTerminal, ifcElement);
     // flowTerminal.setGlobalId(ifcElement.getGlobalId());
     // convertedObjects.put(ifcElement, flowTerminal);
   }
 }