From 411855495efd20f2cfe0a459d2fe3bc47606ee23 Mon Sep 17 00:00:00 2001 From: Laurens Oostwegel Date: Sun, 16 May 2021 18:16:59 +0200 Subject: [PATCH] support for CityJSON MultiSurface, CompositeSurface & interior faces for cityjson2ifc convert --- src/ifccityjson/cityjson2ifc.py | 1 + src/ifccityjson/geometry.py | 45 +++++++++++++++++++++++---------- 2 files changed, 33 insertions(+), 13 deletions(-) diff --git a/src/ifccityjson/cityjson2ifc.py b/src/ifccityjson/cityjson2ifc.py index 20aa39a32b..3c3c896d75 100644 --- a/src/ifccityjson/cityjson2ifc.py +++ b/src/ifccityjson/cityjson2ifc.py @@ -78,6 +78,7 @@ class Cityjson2ifc: self.IFC_model = ifcopenshell.api.run("project.create_file") self.IFC_project = ifcopenshell.api.run("root.create_entity", self.IFC_model, **{"ifc_class": "IfcProject"}) self.properties["owner_history"] = self.create_owner_history() + ifcopenshell.api.run("unit.assign_unit", self.IFC_model) self.IFC_representation_context = ifcopenshell.api.run("context.add_context", self.IFC_model, **{"context": "Model"}) self.IFC_representation_sub_context = ifcopenshell.api.run("context.add_context", self.IFC_model, diff --git a/src/ifccityjson/geometry.py b/src/ifccityjson/geometry.py index 3eaf84ea30..af7a6c8122 100644 --- a/src/ifccityjson/geometry.py +++ b/src/ifccityjson/geometry.py @@ -21,6 +21,9 @@ class GeometryIO: return self.create_IFC_closed_shell(IFC_model, geometry) 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") return @@ -31,8 +34,7 @@ class GeometryIO: outershell = shell[0] faces = [] for face in outershell: # exterior shell - for triangle in face: - faces.append(self.create_IFC_face(IFC_model, triangle)) + faces.append(self.create_IFC_face(IFC_model, face)) shells.append(IFC_model.create_entity("IfcClosedShell", faces)) IFC_geometry = IFC_model.create_entity("IfcShellBasedSurfaceModel", shells) @@ -43,8 +45,7 @@ class GeometryIO: # print(geometry.surfaces[0]['surface_idx'][0]) faces = [] for face in outershell: # exterior shell - for triangle in face: - faces.append(self.create_IFC_face(IFC_model, triangle)) + faces.append(self.create_IFC_face(IFC_model, face)) if len(geometry.boundaries) == 1: shell = IFC_model.create_entity("IfcClosedShell", faces) @@ -60,22 +61,40 @@ class GeometryIO: # print(triangle) # print(geometry.boundaries) - def create_IFC_surface(self, IFC_model, geometry, surface_id): - face_ids = geometry.surfaces[surface_id]["surface_idx"] - faces = [] + def create_IFC_surface(self, IFC_model, geometry, surface_id=None): + faces = None + if surface_id is not None: + face_ids = geometry.surfaces[surface_id]["surface_idx"] + faces = list(map(lambda face_id: geometry.boundaries[face_id[0]][face_id[1]], face_ids)) + else: + faces = geometry.boundaries - for shell, face_id in face_ids: - for triangle in geometry.boundaries[shell][face_id]: - faces.append(self.create_IFC_face(IFC_model, triangle)) + IFC_faces = [] + for face in faces: + IFC_faces.append(self.create_IFC_face(IFC_model, face)) - shell = IFC_model.create_entity("IfcOpenShell", faces) + shell = IFC_model.create_entity("IfcOpenShell", IFC_faces) IFC_geometry = IFC_model.create_entity("IfcShellBasedSurfaceModel", [shell]) return IFC_geometry def create_IFC_face(self, IFC_model, face): + # exterior face vertices = [] - for vertex in face: + for vertex in face[0]: vertices.append(self.vertices[tuple(vertex)]) polyloop = IFC_model.create_entity("IfcPolyLoop", vertices) outerbound = IFC_model.create_entity("IfcFaceOuterBound", polyloop, True) - return IFC_model.create_entity("IfcFace", [outerbound]) \ No newline at end of file + + # return if only exterior face + if len(face) == 1: + return IFC_model.create_entity("IfcFace", [outerbound]) + + # interior face + innerbounds = [] + for interior_face in face[1:]: + 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)) + return IFC_model.create_entity("IfcFace", [outerbound] + innerbounds) +