From 13209b6d03d361b650527c4dfb615a675422c1bf Mon Sep 17 00:00:00 2001 From: Laurens Oostwegel Date: Sun, 16 May 2021 18:55:00 +0200 Subject: [PATCH] Create mapping to IFC for all CityJSON object types & semantic surfaces --- src/ifccityjson/README.md | 5 +++-- src/ifccityjson/cityjson2ifc.py | 33 ++++++++++++++++++++------------- src/ifccityjson/geometry.py | 13 ++++++------- 3 files changed, 29 insertions(+), 22 deletions(-) diff --git a/src/ifccityjson/README.md b/src/ifccityjson/README.md index a97e0cb02a..95183145ed 100644 --- a/src/ifccityjson/README.md +++ b/src/ifccityjson/README.md @@ -6,7 +6,7 @@ Converter for CityJSON files and IFC. Currently only supports one-way conversion IFCCityJSON only came into being 14/04/2021. Be prepared for lots of bugs, unfinished implementations and little to no documentation! ## Dependencies -- [IfcOpenShell](https://github.com/IfcOpenShell/IfcOpenShell) +- [IfcOpenShell](https://github.com/IfcOpenShell/IfcOpenShell) (also IfcOpenShell api is needed) - [CJIO](https://github.com/cityjson/cjio) ## Usage of IFCCityJSON @@ -22,7 +22,7 @@ The example file that could be used is example/3D_BAG_example.json - [ ] "MultiPoint" - [ ] "MultiLineString" - [x] "MultiSurface" -- [ ] "CompositeSurface" +- [x] "CompositeSurface" - [x] "Solid": exterior shell - [ ] "Solid": interior shell - [x] "MultiSolid" @@ -33,5 +33,6 @@ The example file that could be used is example/3D_BAG_example.json - [x] CityJSON Attributes as IFC properties in 'CityJSON_attributes' pset - [x] Implement georeferencing - [x] Do not use template IFC for new IFC file, but make IFC file from scratch +- [x] Create mapping to IFC for all CityJSON object types & semantic surfaces - [ ] Implement conversion of all geometries - [ ] Implement conversion of all LODs instead of online the most detailed diff --git a/src/ifccityjson/cityjson2ifc.py b/src/ifccityjson/cityjson2ifc.py index 3c3c896d75..2a53cb1833 100644 --- a/src/ifccityjson/cityjson2ifc.py +++ b/src/ifccityjson/cityjson2ifc.py @@ -10,23 +10,33 @@ JSON_TO_IFC = { "Road": ["IfcCivilElement"], "TransportSquare": ["IfcSpace"], "TINRelief": ["IfcGeographicElement"], - "WaterBody": ["IfcGeographicElement"], + "WaterBody": ["IfcGeographicElement"], # Update for IFC4.3 "LandUse": ["IfcGeographicElement"], "PlantCover": ["IfcGeographicElement"], "SolitaryVegetationObject": ["IfcGeographicElement"], "CityFurniture": ["IfcFurnishingElement"], "GenericCityObject": ["IfcCivilElement"], - "Bridge": ["IfcCivilElement"], - "BridgePart": ["IfcCivilElement"], - "BridgeInstallation": ["IfcCivilElement"], - "BridgeConstructionElement": ["IfcCivilElement"], - "Tunnel": ["IfcCivilElement"], - "TunnelPart": ["IfcCivilElement"], - "TunnelInstallation": ["IfcCivilElement"], + "Bridge": ["IfcCivilElement"], # Update for IFC4.3 + "BridgePart": ["IfcCivilElement"], # Update for IFC4.3 + "BridgeInstallation": ["IfcCivilElement"], # Update for IFC4.3 + "BridgeConstructionElement": ["IfcCivilElement"], # Update for IFC4.3 + "Tunnel": ["IfcCivilElement"], # Update for IFC4.3 + "TunnelPart": ["IfcCivilElement"], # Update for IFC4.3 + "TunnelInstallation": ["IfcCivilElement"], # Update for IFC4.3 "CityObjectGroup": ["IfcCivilElement"], - "GroundSurface": ["IfcSlab"], + "GroundSurface": ["IfcSlab", {"PredefinedType": "BASESLAB"}], "RoofSurface": ["IfcRoof"], - "WallSurface": ["IfcWall"] + "WallSurface": ["IfcWall"], + "ClosureSurface": ["IfcSpace"], + "OuterCeilingSurface": ["IfcCovering", {"PredefinedType": "CEILING"}], + "OuterFloorSurface": ["IfcSlab", {"PredefinedType": "FLOOR"}], + "Window": ["IfcWindow"], + "Door": ["IfcDoor"], + "WaterSurface": ["IfcGeographicElement"], # Update for IFC4.3 + "WaterGroundSurface": ["IfcGeographicElement"], # Update for IFC4.3 + "WaterClosureSurface": ["IfcGeographicElement"], # Update for IFC4.3 + "TrafficArea": ["IfcCivilElement"], # Update for IFC4.3 + "AuxiliaryTrafficArea": ["IfcCivilElement"] # Update for IFC4.3 } class Cityjson2ifc: @@ -90,9 +100,6 @@ class Cityjson2ifc: **{"ifc_class": "IfcSite", "name": "My Site"}) - # self.IFC_representation_sub_context = self.IFC_model.by_type("IFCGEOMETRICREPRESENTATIONSUBCONTEXT")[0] - # self.IFC_representation_context = self.IFC_model.by_type("IFCGEOMETRICREPRESENTATIONCONTEXT")[0] - def create_owner_history(self): actor = self.IFC_model.createIfcActorRole("ENGINEER", None, None) person = self.IFC_model.createIfcPerson("Oostwegel", None, "L.J.N.", None, None, None, (actor,)) diff --git a/src/ifccityjson/geometry.py b/src/ifccityjson/geometry.py index af7a6c8122..e483d3e6e5 100644 --- a/src/ifccityjson/geometry.py +++ b/src/ifccityjson/geometry.py @@ -22,7 +22,6 @@ class GeometryIO: elif geometry.type in ["CompositeSolid", "MultiSolid"]: return self.create_IFC_composite_closed_shell(IFC_model, geometry) elif geometry.type in ["CompositeSurface", "MultiSurface"]: - print('compose or multisurface') return self.create_IFC_surface(IFC_model, geometry) else: warnings.warn("Types other than solids are not yet supported") @@ -31,9 +30,10 @@ class GeometryIO: def create_IFC_composite_closed_shell(self, IFC_model, geometry): shells = [] for shell in geometry.boundaries: + # exterior shell outershell = shell[0] faces = [] - for face in outershell: # exterior shell + for face in outershell: faces.append(self.create_IFC_face(IFC_model, face)) shells.append(IFC_model.create_entity("IfcClosedShell", faces)) @@ -41,10 +41,10 @@ class GeometryIO: return IFC_geometry def create_IFC_closed_shell(self, IFC_model, geometry): + # exterior shell outershell = geometry.boundaries[0] - # print(geometry.surfaces[0]['surface_idx'][0]) faces = [] - for face in outershell: # exterior shell + for face in outershell: faces.append(self.create_IFC_face(IFC_model, face)) if len(geometry.boundaries) == 1: @@ -55,11 +55,10 @@ class GeometryIO: # TODO: INTERIOR SHELL warnings.warn("Solid interior shell not yet supported") return - # for boundary in geometry.boundaries[1]: # interior shell + # for boundary in geometry.boundaries[1:]: # interior shells # for face in boundary: # for triangle in face: # print(triangle) - # print(geometry.boundaries) def create_IFC_surface(self, IFC_model, geometry, surface_id=None): faces = None @@ -95,6 +94,6 @@ class GeometryIO: for vertex in interior_face: vertices.append(self.vertices[tuple(vertex)]) polyloop = IFC_model.create_entity("IfcPolyLoop", vertices) - innerbounds.append(IFC_model.create_entity("IfcFaceOuterBound", polyloop, True)) + innerbounds.append(IFC_model.create_entity("IfcFaceBound", polyloop, True)) return IFC_model.create_entity("IfcFace", [outerbound] + innerbounds)